Reputation: 529
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 like
return = MaybeT . return . Just
But I read that "It would also have been possible (though arguably less readable) to write return = MaybeT . return . return"
, this confused me.
How does return = MaybeT . return . return
equals to return = MaybeT . return . Just
?
Upvotes: 2
Views: 194
Reputation:
Consider MaybeT
's definition:
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
First return
definition (read it from down to 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 a monad too. It's return
is a Just
. That's why second MaybeT
's 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's the same as `Just` for `Maybe`: Maybe a
Upvotes: 7
Reputation: 74354
In Haskell functions like return
are polymorphic. If you examine the type of return
you'll see that it's return :: Monad m => a -> m a
which indicates that it works for any monad. As it turns out, Maybe
is a monad and so there must be (somewhere in the standard libraries) an instance
declaration like
instance Monad Maybe where
return = ...
...
and, as it turns out, the instance definition of return
for Maybe
is
instance Monad Maybe where
return = Just
So that 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 decide what the "actual" type of a polymorphic function is. So, to be clear, what's happening in your example is that Haskell is able to recognize that the rightmost return
must return a value wrapped in Maybe
and thus knows to specialize return
to return :: a -> Maybe a
and then it uses the instance Monad Maybe
definition for return
and turns it into Just
.
Upvotes: 5