为什么“失败”(来自镜头)会产生无效的遍历?

时间:2014-11-25 23:41:11

标签: haskell lens

来自the documentation

  

尝试第一个Traversal(或Fold),如果没有返回任何条目,请回到第二个Traversal(或Fold)。

     

如果第二个Traversal与第一个Traversal的结果不相交或返回完全相同的结果,则这只是一个有效的failing

是否有{{1}}生成的无效遍历的简单示例以及展示它的测试用例?

1 个答案:

答案 0 :(得分:7)

对于反例,让我们首先定义一个新的数据类型,我们使用makePrisms为其生成遍历:

data T = A T | C deriving Show
makePrisms ''T

_A :: Traversal T T现在是一个有效的遍历。现在,使用failing

构建一个新的遍历
t :: Traversal' T T
t = failing _A id

请注意,(C & t .~ A C) ^.. t = [C]看起来像是违反了遍历法(你没有“得到你输入的内容”)。实际上,第二个遍历法是:

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

不满意,可以通过fg的以下选项看到:

-- getConst . t f = toListOf t
f :: T -> Const [T] T
f = Const . (:[])

-- runIdentity . t g = t .~ A C
g :: T -> Identity T
g = pure . const (A C)

然后:

> getConst . runIdentity . fmap (t f) . t g $ C
[C]

虽然:

> getConst . runIdentity . getCompose . t (Compose . fmap f . g) $ C
[A C]

所以确实有一种情况,failing有效遍历不会产生有效的遍历。