Scalaz Lens Composition


Really simple question here. After watching an excellent introduction to lenses:

I thought I might attempt one of the simple examples covered in the talk:

import scalaz.Lens._

this was followed by this error

error: type mismatch;
 found   : scalaz.Lens[(Nothing, Nothing),Nothing]
 required: scalaz.Lens[(Nothing, Nothing),C]
Note: Nothing <: C, but class Lens is invariant in type B.
You may wish to define B as +B instead. (SLS 4.5)

Any ideas as to how to make this work?

You're going to need to help the compiler out a bit. Either of the following would do:

(fst andThen snd[Int, Int]).set(((1, 2), 3), 9)


(fst[(Int, Int), Int] andThen snd).set(((1, 2), 3), 9)

My guess would be that Edward Kmett glossed over this issue in the talk because it's not really relevant to his subject—it's just one of the (annoying) quirks of Scala's type inference system. In Haskell, for example, the following would be fine:

setL (sndLens . fstLens) 9 ((1, 2), 3)

You can read the answers here for more information about the limitations of type inference in Scala.