Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple haskell lens from tutorial violates lens law

I'm reading this tutorial:

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

and my code looks like this:

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

Now following the blog post, here are some common lens computations:

*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"]

The last evaluation has left me confused. Isn't the following lens law supposed to hold?

view l (set l v s) = v

(The law is taken from http://artyom.me/lens-over-tea-2.)

like image 943
danpomaro Avatar asked Dec 08 '25 10:12

danpomaro


1 Answers

This is a lens law, and tp is a traversal, so it doesn't have to abide by this law.

Strictly speaking, view shouldn't work with traversals at all (it works anyway, but it does so by combining the gathered results monoidally).

like image 142
Artyom Avatar answered Dec 10 '25 10:12

Artyom