我正在使用xml-lens包来处理XML。
鉴于Element
,我想对其concatMap
字段执行类似elementNode :: [Node]
的计算。具体来说,满足某些条件的NodeElement
应该产生更多的NodeElement
,而所有其他情况(其余NodeElement
和其他Node
构造函数应该产生一个单例列表。然后应将其串联到[Node]
中,并用作覆盖给定elementNode
的当前Element
的值。
我正在努力写出合适的镜头咒语来做到这一点。到目前为止,这是我设法提出的:
over nodes $ concatMapOf someLensMagic (myFun :: Element -> [Node])
它进行类型检查,但是我无法实现someLensMagic
。非常感谢您的帮助。
答案 0 :(得分:1)
如果$(document).ready(function () {
AjaxInit();
$(document).ajaxComplete(function () {
AjaxInit()
});
});
function AjaxInit() {
alert("test");
}
解释了如何使用myFun
构造函数,并且您想为其他NodeElement
构造函数提供一个空列表,则可以使用Node
。
要为其他构造函数提供单例列表,应修改concatMapOf _Element
以处理myFun
的所有构造函数。然后,您可以使用Node
,而不是concatMap myFun
。 (在这种情况下,您可以使用concatMapOf
,但很难理解。)
由于无法从concatMapOf traverse myFun
中提取someLensMagic
,因此无法编写将生成单例列表的Element
。
答案 1 :(得分:1)
最直接的解决方案是much like bergey suggests,在myFun
周围编写包装器,以便它可以处理Node
而不是Element
s:
myFun' :: Node -> [Node]
myFun' n = case n of
NodeElement el -> myFun el
_ -> [n]
然后,可以将 myFun'
与普通concatMap
(而不是concatMapOf
)一起使用,以修改nodes
字段:
over nodes (concatMap myFun')
碰巧,有一部分 lens 魔术可以用作编写包装器的替代方法。 outside
组合器将棱镜变成瞄准功能的透镜,实际上,我们可以编辑功能在特定情况下的功能。实际上,它看起来像这样:
over nodes (concatMap $ set (outside _Element) myFun (:[]))
concatMap
的参数的功能类似于(:[])
,除非该参数与_Element
匹配,在这种情况下,它变为基础元素上的myFun
。也就是说,实质上是抽象的模式匹配。为了说明这一点,我们可以尝试使用myFun'
模仿上面outside
的定义样式:
myFun' :: Node -> [Node]
myFun'
= outside _Element .~ myFun
$ \n -> [n]
答案 2 :(得分:0)
一种在Fold
中对某些子节点进行不同处理的方法是,根据情况使用to
将其置于Either
的不同分支中,然后使用{{3 }},该函数可让您将不同的Traversal
应用于Either
的每个分支。
例如,此函数应返回Node
的子Element
,其特殊之处在于,对于满足条件的节点,将返回其子节点:
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)
答案 3 :(得分:0)
我结束了两个连续的concatMap
:
over nodes (concatMap $ concatMapOf _Element myFun) element
这是次优的解决方案,因此我不会将其标记为答案,也欢迎其他任何建议。