为HXT计算和过滤箭头

Jor*_*Diz 6 state haskell arrows hxt

我正在尝试解析XML,但我想过滤和提取给定节点中确定数量的子节点.例如:

<root>
    <node id="a" />
    <node id="b" />
    <node id="c" />
    <node id="d" />
</root>
Run Code Online (Sandbox Code Playgroud)

然后,如果我执行箭头getChildren >>> myFilter 2,我将只返回ID为"a"和"b"的节点.

直觉让我应该用状态箭来跟踪,但我不知道该怎么做.

我试着自己做,但这不是我想要的,看起来不是很优雅,也不行.我尝试运行我的箭头链runSLA和一个整数参数作为初始状态,然后定义:

takeOnly :: IOSLA Int XmlTree XmlTree
takeOnly = changeState (\s b -> s-1)
             >>> accessState (\s b -> if s >= 0 then b else Nothing)
Run Code Online (Sandbox Code Playgroud)

但当然我无法返回Nothing,我需要返回一个XmlTree.但我根本不想回报任何东西!

可能有更好的方法.你能帮助我吗?

感谢您的时间和帮助!

Tra*_*own 4

使用Control.Arrow.ArrowList中的组合器来处理这种事情可能会更惯用。

\n\n

该包特别提供了(>>.) :: a b c -> ([c] -> [d]) -> a b d,它是“将列表箭头的结果转换为另一个列表的组合器”。这允许我们在此上下文中使用take已有的列表函数。

\n\n

这是如何使用它的快速版本:

\n\n
module Main where\n\nimport Text.XML.HXT.Arrow\n\ntakeOnly :: (ArrowXml a) => Int -> a XmlTree XmlTree\ntakeOnly n = getChildren >>. take n \n\nmain = do\n  let xml = "<root><node id=\'a\' /><node id=\'b\' />\\\n                  \\<node id=\'c\' /><node id=\'d\' /></root>"\n\n  print =<< runX (readString [] xml >>> getChildren >>> takeOnly 2)\n
Run Code Online (Sandbox Code Playgroud)\n\n

我相信这大约符合您正在寻找的内容:

\n\n
travis@sidmouth% ./ArrowTake\n[NTree (XTag (LP node) [NTree (XAttr (LP id)) [NTree (XText "a") []]]) [],\n NTree (XTag (LP node) [NTree (XAttr (LP id)) [NTree (XText "b") []]]) []]\n
Run Code Online (Sandbox Code Playgroud)\n\n

没有IOSLA要求。请注意,我还稍微更改了函数类型\xe2\x80\x94这个版本对我来说似乎更好,但您可以轻松地将其转换为更像您版本中的类型。

\n