I have been working out on the examples given out in this article for creating Lenses.
I created Lens
as stated in the article and the following is my code:
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
type Degrees = Double
type Latitude = Degrees
type Longitude = Degrees
data Meetup = Meetup { _name :: String, _location :: (Latitude, Longitude) }
makeLenses ''Meetup
meetupLat = location._1 :: Lens' Meetup Latitude
Now this code doesn't typecheck unless I include this:
{-# LANGUAGE NoMonomorphismRestriction #-}
But no where in the article, I could find out that they have mentioned about the monomorphism restriction. So is this an normal thing or am I doing something wrong here ?
Compiler used: GHC 7.6.2
This is a normal thing. The lens
library relies heavily on polymorphism, so the monomorphism restriction (which makes things less polymorphic than they could be) doesn't interact so well with it. In your case, I think you could also write your code like this:
meetupLat :: Lens' Meetup Latitude
meetupLat = location._1
If you provide an explicit polymorphic type signature for a binding, the monomorphism restriction doesn't matter.
Note that Lens' Meetup Latitude
is a polymorphic type, even though it looks monomorphic. The type variables are hidden inside the Lens'
type synonym. In particular:
Lens' Meetup Latitude
is defined as Lens Meetup Meetup Latitude Latitude
.
And Lens Meetup Meetup Latitude Latitude
is defined as forall f. Functor f => (Meetup -> f Meetup) -> Latitude -> f Latitude
So this is all about the f
. I think the monomorphism restriction would force a concrete instantiation of f
, but you want to keep it polymorphic because different users of the lens will choose different f
. For example view
will choose Const
and set
will choose Identity
. So it is really important to keep the f
polymorphic to allow the users of the lens these choices.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With