教程中的简单 Haskell 镜头违反了镜头定律

dan*_*aro 3 haskell haskell-lens

我正在阅读本教程:

http://blog.jakubarnold.cz/2014/08/06/lens-tutorial-stab-traversal-part-2.html

我的代码如下所示:

import Control.Applicative
import Data.Traversable
import Control.Lens

data User = User String [Post] deriving Show
data Post = Post String deriving Show

posts :: Lens' User [Post]
posts f (User n p) = fmap (User n) (f p)

users :: [User]
users = [User "john" [Post "hello", Post "world"], User "bob" [Post "foobar"]]

tp :: (Traversable t, Applicative f) => ([Post] -> f [Post]) -> t User -> f (t User)
tp = traverse . posts
Run Code Online (Sandbox Code Playgroud)

现在跟随博客文章,这里有一些常见的镜头计算:

*Main> view tp users
[Post "hello",Post "world",Post "foobar"]

*Main> set tp [Post "x",Post "y"] users
[User "john" [Post "x",Post "y"],User "bob" [Post "x",Post "y"]]

*Main> view tp (set tp [Post "x",Post "y"] users)
[Post "x",Post "y",Post "x",Post "y"]
Run Code Online (Sandbox Code Playgroud)

最后的评价让我一头雾水。以下镜头定律不是应该成立吗?

view l (set l v s) = v
Run Code Online (Sandbox Code Playgroud)

(法律摘自http://artyom.me/lens-over-tea-2。)

Art*_*yom 5

这是一个镜头定律,tp是一个遍历,所以它不必遵守这个定律。

严格来说,view根本不应该使用遍历(无论如何它都可以工作,但它是通过将收集到的结果以幺半群方式组合来实现的)。

  • @danpomaro 是的。`镜头+镜头`=镜头;`lens + traversal` = `traversal + lens` = `traversal + traversal` = traversal。 (2认同)