我一直在使用hxt没有问题,但从一开始就出现了问题。 看,想象下面的一段代码
liftKeys = atTag "myKeys" >>>
proc e -> do
key1 <- getAttrValue "name" -< e
key2 <- getAttrValue "chance" -< e
returnA -< (key1, key2)
我使用它就像通过许多文档来解析,并且在经典的programmig问题之前,我缺乏抽象。
<zone id= "greenhill">
<key name="a" chance = "10" />
<key name="v" chance = "10"/>
</zone>
我有四个(以及更多即将发布的)文件要解析,就像这个例子一样。有些有2个属性,有些有5个,有些有1个等等 我根据文件的属性数量不能编写不同版本的liftKeys。事情是我真的不明白箭头或我正在做什么u.u 必须有一些折叠或其他东西来编写更简单的代码。
你知道更好地利用这个吗?
答案 0 :(得分:3)
如果您拥有不同数量的属性,那么从属性名称列表构建箭头似乎是最自然的解决方案。但是,要做到这一点,我们需要一个小帮助函数将箭头列表转换为生成列表的单箭头。
arrowList :: Arrow a => [a b c] -> a b [c]
arrowList [] = arr $ const []
arrowList (a:arrows) = proc b -> do
c <- a -< b
cs <- arrowList arrows -< b
returnA -< (c:cs)
在某些箭头实用程序库中可能存在这样的东西,但我无法通过快速搜索找到它。在这里,给定一个箭头[a b c]
列表,我们将它们合并为一个箭头,首先将b
提供给第一个箭头,然后递归合并列表的其余部分并将b
提供给合并箭头。
我使用箭头符号编写了上述函数,以便更容易解释,但您可以像这样实现它:
arrowList :: Arrow a => [a b c] -> a b [c]
arrowList [] = arr $ const []
arrowList (a:arrows) = a &&& arrowList arrows >>> arr (uncurry (:))
现在我们可以像这样实现liftKeys
函数
liftKeys :: ArrowXml a => [String] -> a XmlTree [String]
liftKeys keys = atTag "myKeys" >>> arrowList (map getAttrValue keys)
上面的原始示例可以表示为liftKeys ["name", "chance"]
。