以下表达方式的意图有何不同?我很惊讶他们实际上在下面的例子中输入检查并产生不同的结果。
(./) ::
Plated a =>
Traversal s t a a -> Traversal a a u v -> Traversal s t u v
-- Defined in âText.XML.Lensâ
infixr 9 ./
和
(.) :: (b -> c) -> (a -> b) -> a -> c -- Defined in âGHC.Baseâ
infixr 9 .
它们如何与典型的pom.xml文件一起使用:
*Main> x ^.. root ./ ell "version" . text
["1.0-SNAPSHOT"]
*Main> x ^.. root ./ ell "version" ./ text
[]
,其中
text ::
Control.Applicative.Applicative f =>
(Data.Text.Internal.Text -> f Data.Text.Internal.Text)
-> Element -> f Element
-- Defined in âText.XML.Lensâ
和
data Element
= Element {elementName :: Name,
elementAttributes :: containers-0.5.5.1:Data.Map.Base.Map
Name Data.Text.Internal.Text,
elementNodes :: [Node]}
-- Defined in âText.XMLâ
instance Plated Element -- Defined in âText.XML.Lensâ
答案 0 :(得分:2)
(./)
基于Plated
实例,该实例是具有相同类型“子”的类型。 HTML元素,数学表达式的AST等等。
这里(.)
只是遍历链。所以
*Main> x ^.. root ./ ell "version" . text
["1.0-SNAPSHOT"]
使用本地名称==“version”转到根节点的所有子节点,并收集其中的文本内容。 (这里只有一个这样的节点)
然而, (./)
增加了一个额外的步骤。
*Main> x ^.. root ./ ell "version" ./ text
[]
这适用于具有本地名称==“version”的根节点的任何子节点,然后关注这些节点的所有子节点并选择其中的文本内容。如果没有找到子项,则生成的遍历很可能不会指向任何结果,这可能是您获得空列表的原因。
基本上,l ./ l'
遍历l
所描述的内容,产生了许多目标,然后将焦点从这些目标中的每一个切换到“相同类型的孩子”(如Plated
实例),然后使用l'
遍历这些。
请注意,您必须在root之后使用./
,因为您希望下载到根节点的所有直接子节点,只选择具有您感兴趣的名称的子节点。但是在查看"version"
元素的内容时,您只需要内部的直接内容,无需进一步遍历子元素,因此必须使用(.)
而不是{{1 }}