用镜头保存位置

时间:2014-05-01 02:57:02

标签: haskell lens

我正在尝试使用xml-conduit和xml-lens来解析和遍历XML文档。我不想多次遍历文档的相同部分,而是希望将遍历存储到上一点,然后进一步向下钻取。

离。

let pos = doc ^. root . el "foo"
    bar = pos . text
    baz = pos ./ el "quux" . text

当我尝试这样做时,我收到以下错误:

No instance for (Data.Monoid.Monoid Element)
  arising from a use of `el'
Possible fix:
  add an instance declaration for (Data.Monoid.Monoid Element)
In the second argument of `(.)', namely `el "foo"'
In the second argument of `(^.)', namely `root . el "foo"'
In the expression: doc ^. root . el "foo"

我可以做些什么来存储这个中间位置?

1 个答案:

答案 0 :(得分:1)

发生类型错误是因为elTraversal。遍历指向多个值(在本例中为所有foo元素)。另一方面,(^.)始终返回单个值。只有当目标类型为(^.)时,才能将TraversalMonoid一起使用;在这种情况下,使用mappend将多个值粉碎为单个值。但是,Element不是Monoid(因为没有合理的方法将XML元素组合到单个元素中),因此(^.)不起作用。要获取匹配的XML元素,您应该使用(^..)代替它,这将把它们作为列表返回。

至于正确的问题("我可以做些什么来存储这个中间位置?"),Traversal是对位置的引用,所以如果你想进一步构成它你不想" dereference"它与(^.)(^..)。以下应该有效:

let pos = root . el "foo"
    baz = pos ./ el "quux" . text
    elemTexts = doc ^.. baz