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

?

+3


source to share


2 answers


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

.

+5


source


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

      

+5


source







All Articles