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

Art*_*yom 15 haskell haskell-lens

文档:

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

只有Traversal当第二个Traversal与第一个结果不相交或返回完全相同的结果时,这才有效.

是否有一个简单的示例,failing表明由此产生的无效遍历和一个展示它的测试用例?

ben*_*ofs 7

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

data T = A T | C deriving Show
makePrisms ''T
Run Code Online (Sandbox Code Playgroud)

_A :: Traversal T T现在是一个有效的遍历.现在,使用failing以下命令构造一个新的遍历:

t :: Traversal' T T
t = failing _A id
Run Code Online (Sandbox Code Playgroud)

请注意(C & t .~ A C) ^.. t = [C],看起来它没有通过遍历法(你没有"得到你输入的内容").实际上,第二个遍历法是:

fmap (t f) . t g ? getCompose . t (Compose . fmap f . g)
Run Code Online (Sandbox Code Playgroud)

这是不满意的,可以通过以下选择看到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)
Run Code Online (Sandbox Code Playgroud)

然后:

> getConst . runIdentity . fmap (t f) . t g $ C
[C]
Run Code Online (Sandbox Code Playgroud)

而:

> getConst . runIdentity . getCompose . t (Compose . fmap f . g) $ C
[A C]
Run Code Online (Sandbox Code Playgroud)

因此确实存在failing有效遍历不会产生有效遍历的情况.