我正在尝试与 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")]
在这个函数的帮助下,很容易使用&&&
组合器来配对两个不同节点的文本,然后,比如说,将它传递给构造函数,如下所示:
> parse (extract "a" &&& extract "b" >>^ arr (\(a,b) -> (b,a)))
[("bar","foo")]
现在到了我不明白的部分:我想左因子!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上有一个箭头“教程” ,按照我的理解,它应该可以做我想做的事情——即使&&&
用来配对两个计算的结果。
它也确实有效——但只是在箭头链的开始,而不是在低谷的中间,当我已经有了一些结果时,我想保持“共享”。我有一种感觉,就是无法理解正常函数组合和箭头符号之间的想法差异。我会非常感谢任何指针!(即使它只是一些比 Haskell-wiki 更深入的通用箭头教程。)
谢谢!