Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用lens折叠XML元素的节点?_Xml_Haskell_Haskell Lens - Fatal编程技术网

如何使用lens折叠XML元素的节点?

如何使用lens折叠XML元素的节点?,xml,haskell,haskell-lens,Xml,Haskell,Haskell Lens,我正在使用包来处理XML 给定一个,我想在它的elementNode::[Node]字段上执行类似于concatMap的计算。具体来说,满足某些条件的NodeElement应该生成更多的NodeElements,而所有其他情况(其余的NodeElements和其他Node构造函数)都应该生成一个单例列表。然后,它应该连接到[Node]中,并用作覆盖给定元素的当前元素Node的值 我正在努力写合适的镜头咒语来做到这一点。以下是我到目前为止的想法: over nodes $ concatMapOf

我正在使用包来处理XML

给定一个,我想在它的
elementNode::[Node]
字段上执行类似于
concatMap
的计算。具体来说,满足某些条件的
NodeElement
应该生成更多的
NodeElement
s,而所有其他情况(其余的
NodeElement
s和其他
Node
构造函数)都应该生成一个单例列表。然后,它应该连接到
[Node]
中,并用作覆盖给定
元素的当前
元素Node
的值

我正在努力写合适的镜头咒语来做到这一点。以下是我到目前为止的想法:

over nodes $ concatMapOf someLensMagic (myFun :: Element -> [Node])

它会进行类型检查,但我无法实现
someLensMagic
。非常感谢您的帮助。

如果
myFun
解释了如何使用
NodeElement
构造函数,并且您希望为其他
节点
构造函数创建一个空列表,您可以使用
concatMapOf\u元素

要为其他构造函数提供单例列表,您应该修改
myFun
以处理
Node
的所有构造函数。然后您可以使用
concatmapmyfun
,而不是
concatMapOf
。(在本例中,您可以使用
concatMapOf traverse myFun
,但这更难理解。)


无法编写将生成单例列表的
someLensMagic
,因为无法从
NodeComment
中提取
元素.

折叠中以不同方式处理某些子节点的一种方法,它用于根据条件将它们放置在
任一
的不同分支中,然后使用一个函数,该函数允许您对
任一
的每个分支应用不同的
遍历

例如,此函数应返回
元素
的子
节点
,其特殊性是,对于满足条件的节点,将返回其子节点:

foldDifferently :: (Node -> Bool) -> Fold Element Node
foldDifferently p =
      nodes 
    . folded 
    . to (\n -> if p n then Right n else Left n) 
    . beside id (_Element . nodes . folded)

我已经完成了两个连续的
concatMap
s:

over nodes (concatMap $ concatMapOf _Element myFun) element

这是次优的解决方案,因此我不会将其标记为答案,并欢迎任何其他建议。

最严格的解决方案是,在
myFun
周围编写一个包装器,以便它可以处理
节点
而不是
元素
s:

myFun'::Node->[Node]
myFun'n=案例n
NodeElement el->myFun el
_->[n]
myFun'
然后可以与普通的
concatMap
(与
concatMapOf
)一起使用,以修改
节点
字段:

over节点(concatMap myFun')
碰巧,有一种镜头魔术可以作为书写包装的替代方法。组合器将一个棱镜变成一个瞄准函数的透镜,使我们实际上可以编辑函数在特定情况下的功能。实际上,它看起来是这样的:

节点上的
(concatMap$set(在_元素之外)myFun(:[]))
concatMap
的参数是一个类似于
(:[])
的函数,除非该参数与
\u元素
匹配,在这种情况下,它在基础元素上变为
myFun
。也就是说,本质上是抽象的模式匹配。为了让大家明白这一点,我们可以尝试使用
outside
模仿上面的
myFun'
的定义风格:

myFun'::Node->[Node]
myFun'
=外部_元素~myFun
$\n->[n]

我真的不想从
NodeComment
中提取
元素。我只想让它保持原样。