2

Control.Arrow.ArrowTreeを使用して、指定されたツリーで最初に変換が成功した後(深さ優先)に停止するHTML処理矢印を作成しようとしています。つまり、タイプの関数

processFirst :: (ArrowTree a, Tree t) => a (t b) (t b) -> a (t b) (t b)

たとえば、クラス「first」をHTMLドキュメントの最初のリスト項目に追加するには、矢印を作成します。

processFirst (hasName "li" `guards` addAttr "class" "first")

私はHXTにかなり慣れておらず、APIドキュメントを数時間読んで実装方法を理解しようとしprocessFirstていますが、すべてを組み合わせることができませんでした。processTopDownUntil最初は有望に聞こえましたが、その関数は特定のサブツリーの処理を停止するだけなので、ネストされた要素を除くすべての要素を変換します。

4

1 に答える 1

1

質問を完全に理解したかどうかはわかりませんが、答えようとします:)

次を試してみましょう:

test = flip runLA undefined $ xshow $
  constA "<xml><x>X1</x><x>X2</x></xml>" >>> xread
  >>> processFirst (hasName "x" `guards` addAttr "class" "first")

processFirst f = f `orElse` processChildren (processFirst f)

の定義は。のprocessFirst定義と同じですprocessTopDownUntil。この関数は次のように出力します。

["<xml><x class=\"first\">X1</x><x class=\"first\">X2</x></xml>"]

問題は明確である必要がありfます。最上位ノードで失敗した場合はprocessFirst、すべての子に対して呼び出されます。f一部の子で成功した場合、他の子の処理を中止する方法が必要です。

考えられる解決策は、状態矢印を使用することです。

processFirst f = fromSLA False process
  where
  process = (getState >>> isA not)
            `guards`
            (f >>> changeState (const $ const True))
            `orElse`
            processChildren process

f成功したときに状態を設定し、処理する前に確認するという考え方です。

注:今は矢印になっているfはずです。SLAそれがあなたが望むものでない場合、あなたはすべての子供を集めて(例えばを使用してlistA)それらを純粋に処理することを試みることができます。

したがって、このソリューションは理想的ではありませんが、出発点として役立つことを願っています。

于 2012-04-21T18:44:12.070 に答える