I have been reading this post to understand lens. They initially define a type synonym like this:
type RefF a b = forall f. Functor f => (b -> f b) -> (a -> f a)
Const is defined like this:
newtype Const a b = Const { getConst :: a }
How does the get
function typecheck:
get :: RefF a b -> a -> b
get r = getConst . r Const
The type of getConst is something like this:
getConst :: Const a b -> a
The type of r Const
which I guess is something like this:
r Const = (b -> f b) -> (Const -> f Const)
Then how does both getConst
and r Const
get's composed to give a -> b
?
The type of r
is obtained by substituting the const functor for f
; since we'll need a b
result that has to be the first argument (only x
is actually found in the Const x y
type)
r :: (b -> Const b b) -> (a -> Const b a)
Now the argument is simple: that's merely the Const
constructor.
r Const :: a -> Const b a
And if you post-compose that with getConst :: Const b a -> b
, you end up with
getConst . r Const :: a -> b