Isaac Dupree wrote:
apfelmus wrote:

  dup :: Lens a (a,a)
  dup = id &&& id

Which component of the pair should

  put dup :: a -> (a,a) -> (a,a)

change? The first, the second, or even both?

[...]
  put :: Lens s a -> a -> s -> s
  put x = flip $ snd . focus x

wouldn't
put dup :: (a,a) -> a -> a

Oops, of course.

Arrows IIRC resolve this dilemma by arbitrarily saying the first argument of (&&&) takes effect first... a solution I'm not entirely happy with. Here, first it would put the first element of the pair, then it would put the second, so the result would be the second element. If it were 2d vectors, x::Lens Vector Double, angle::Lens Vector Angle, it makes a difference whether x-coordinate or angle is changed first, and again, (&&&) could sequence.

I wish there was some way to compose them that guaranteed order-independence, and didn't work otherwise, though. I suppose QuickCheck could be used to catch most parallel/disjoint-assumption-mistakes like that...

The situation is much worse, even dropping order-independence doesn't help: the lens laws

  get x (put x a s) = a
  put x (get x s) s = s

are already violated for  dup ! Assuming that

  get dup :: a -> (a,a)

is total (i.e. first and second component not undefined ), parametric polymorphism dictates that it can only be

  get dup = \a -> (a,a)

Now, we should have

  get dup x (put dup (a,a') s)
     = (put dup (a,a') s, put dup (a,a') s)
     = (a,a')

but that's impossible when a is different from a'.


Regards,
apfelmus

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to