Dragging the return function definition into the MaybeT monad transformer
MaybeT is defined as
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
And, MaybeT m is also an instance of the Monad class, the function return
is defined as
return = MaybeT . return . Just
But I read that "It would also have been possible (though arguably less readable) to write return = MaybeT . return . return"
, it confused me.
How return = MaybeT . return . return
equal return = MaybeT . return . Just
?
source to share
In Haskell functions such as return
are polymorphic. If you examine the type return
, you will see that it return :: Monad m => a -> m a
indicates that it works for any monad. As it turns out, it Maybe
is a monad, so there should be (somewhere in the standard libraries) a declaration instance
like
instance Monad Maybe where
return = ...
...
and, as it turned out, the instance definition return
for Maybe
equals
instance Monad Maybe where
return = Just
So this indicates why we are allowed to replace return
with Just
, but it doesn't explain why Haskell actually does it.
It turns out that Haskell uses type inference to determine what the "actual" type of a polymorphic function is. So, to make it clear what's going on in your example, Haskell can recognize that the rightmost one return
should return a value wrapped in Maybe
, and therefore knows to specialize return
to return :: a -> Maybe a
, and then it uses instance Monad Maybe
for return
and turns it into Just
.
source to share
Consider the definition MaybeT
:
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
First definition return
(read it from page up):
return =
MaybeT . -- put `m (Maybe a)` into `MaybeT`: MaybeT (m (Maybe a))
return . -- put `Maybe a` into external monad: m (Maybe a)
Just -- put value into `Maybe`: Maybe a
Maybe
is also a monad. It return
is equal Just
. Therefore, the second MaybeT
return
defines exactly the same function:
return =
MaybeT . -- put `m (Maybe a)` into `MaybeT`: MaybeT (m (Maybe a))
return . -- put `Maybe a` into external monad: m (Maybe a)
return -- it the same as `Just` for `Maybe`: Maybe a
source to share