Reputation:
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 ?
Upvotes: 0
Views: 54
Reputation: 10793
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.
Upvotes: 5