私は Haskell の XML ツールボックス ( HXT ) を理解しようとしていますが、計算ツールとしての矢印を完全に把握していないように見えるため、どこかで壁にぶつかっています。
GHCiセッションを使用してもう少しよく説明したいと思っていた私の問題は次のとおりです。
> let parse p = runLA (xread >>> p) "<root><a>foo</a><b>bar</b><c>baz</c></root>"
> :t parse
parse :: LA XmlTree b -> [b]
したがって、Parse は、単純な XML ドキュメントに与えた矢印を適用する小さなヘルパー関数です。
<root>
<a>foo</a>
<b>bar</b>
<c>baz</c>
</root>
別のヘルパー関数を定義します。今回は、指定された名前のノードの下にあるテキストを抽出します。
> let extract s = getChildren >>> isElem >>> hasName s >>> getChildren >>> getText
> :t extract
extract :: (ArrowXml cat) =>
String -> cat (Data.Tree.NTree.TypeDefs.NTree XNode) String
> parse (extract "a" &&& extract "b") -- extract two nodes' content.
[("foo","bar")]
この関数の助けを借りて、&&&
コンビネータを使用して 2 つの異なるノードのテキストをペアにし、それを次のようにコンストラクタに渡すのは簡単です。
> parse (extract "a" &&& extract "b" >>^ arr (\(a,b) -> (b,a)))
[("bar","foo")]
ここで、私が理解できない部分が来ます: 私は左因数分解したい! ルートノードを 2 回extract
呼び出します。getChildren
代わりに、一度だけ呼び出したいです! だから私は最初にルートノードの子を取得します
> let extract' s = hasName s >>> getChildren >>> getText
> :t extract'
extract' :: (ArrowXml cat) => String -> cat XmlTree String
> parse (getChildren >>> isElem >>> (extract' "a" &&& extract' "b"))
[]
それが問題かどうかを調べるために、たとえば isElem などの呼び出しの順序を変更しようとしたことに注意してください。しかし、現状では、これが機能しない理由がわかりません。Haskell wiki には「チュートリアル」という矢印があり、私がそれを理解した方法では、その方法でやりたいことを実行できるはず&&&
です。つまり、2 つの計算の結果をペアにするために使用します。
それも機能しますが、「共有」したい結果がすでにある場合は、途中の谷ではなく、矢の連鎖の開始時にのみ. 通常の関数合成とアロー表記の考え方の違いに頭を悩ませているだけな気がします。私はどんな指針にも非常に感謝しています!(Haskell-wiki よりももう少し詳細な一般的な矢印のチュートリアルであっても。)
ありがとうございました!