如何一个接一个地遍历数据结构的不同部分?

时间:2014-05-23 16:18:08

标签: haskell traversal lens

Control.Lens.Traversal中,beside函数遍历Bitraversable的两个部分。给出的例子是

>>> ("hello",["world","!!!"])^..beside id traverse
["hello","world","!!!"]

我可以写一个更明确的beside版本(让我们称之为bothParts)而不是Bitraversable约束需要两个Traversal吗?我想它可以像这样使用:

>>> ("hello",["world","!!!"])^..bothParts _1 _2 id traverse
["hello","world","!!!"]

这已经存在了吗?这样做是否太安全了?谢谢!

编辑:

或者类似的东西:

>>> ("hello",["world","!!!"])^..bothParts _1 (_2.traverse)
["hello","world","!!!"]

1 个答案:

答案 0 :(得分:2)

你想要的组合器应该同时使用2 Traversal s。但是这种组合符一般会违反Traversal定律,特别是“无重复”定律:Traversal应该只遍历每个元素一次。

以下是您可能不想要的示例:

>>> (1, 2) ^.. bothParts _1 _1
[1, 1]    

更准确地说,我想引用Traversal documentation from lens package

  

Traversal t的法律遵循"The Essence of the Iterator Pattern"中所述的Traversable法律。

t pure ≡ pure
fmap (t f) . t g ≡ getCompose . t (Compose . fmap f . g)
  

此要求的一个结果是Traversal需要保留与其开始的后续Traversal的候选项相同数量的元素。对这些法律强度的另一个证明是,“迭代器模式的本质”第5.5节中关于多次遍历相同条目的异域Traversable实例所表达的警告实际上已经被第二定律排除了。同样的论文!