Look at this example:
ReaderT Integer (ErrorT String (StateT Integer Identity)) Integer
What operator bind (>>=) will be used here ?
For example, if we use do notation, then what bind operator will be chosen by compiler ?
1 Answer 1
For reference, (>>=) has the type
(>>=) :: Monad m => m a -> (a -> m b) -> m b
and also note that
ReaderT Integer (ErrorT String (StateT Integer Identity)) Integer
is the same as
(ReaderT Integer (ErrorT String (StateT Integer Identity))) Integer
because type application (like function application) is left associative in Haskell.
So, given
x :: ReaderT Integer (ErrorT String (StateT Integer Identity)) Integer
and an f with the appropriate type, in the expression
x >>= f
the type checker will try to match the type of x with the left argument type of (>>=). This means it will try to unify ReaderT Integer (ErrorT String (StateT Integer Identity)) Integer with m a. The only way that this unifies is by taking a to be Integer and m to be ReaderT Integer (ErrorT String (StateT Integer Identity)). So, using the ~ type equality notation, we end up with
m ~ (ReaderT Integer (ErrorT String (StateT Integer Identity)))
a ~ Integer
As a result, it must use the (ReaderT r n) instance of Monad, where r ~ Integer and n ~ ErrorT String (StateT Integer Identity).
This is a result of how type unification works in Haskell in general, not just for (>>=), so this general idea can be used for interpreting how the type checking of other polymorphic functions works.
5 Comments
f, didn't use the same Monad instance as the left argument the compiler would give a compiler error. Also, if the monad instance of the left argument is left polymorphic but the right argument uses a specific monad, it will match based on the right argument's monad.x >>= f, the compiler tries to match both m a against the type of x and (a -> m b) against the type of f.x :: Maybe Int and f :: Int -> [Bool], then x >>= f won't type check even though both Maybe and [] are Monads. The m can't unify to two different types.
ReaderTs bind. You can look at the source to see what it does.>>=in defined. Most things are defined that way.