0

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 ?

asked Apr 17, 2016 at 21:14
7
  • 2
    ReaderTs bind. You can look at the source to see what it does. Commented Apr 17, 2016 at 21:29
  • From what you know it ? Commented Apr 17, 2016 at 21:29
  • 2
    it's the outermost constructor. The outermost constructor controls it. Commented Apr 17, 2016 at 21:31
  • Is it rule ? Can we something similar about result of run* ? Commented Apr 17, 2016 at 21:47
  • 1
    what is "run*"? It's because of the way >>= in defined. Most things are defined that way. Commented Apr 17, 2016 at 21:49

1 Answer 1

5

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.

answered Apr 17, 2016 at 21:57
Sign up to request clarification or add additional context in comments.

5 Comments

so bind is chosen based on left argument of bind ?
@HaskellFun Not quite. If the return type of the right argument, here called 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.
With x >>= f, the compiler tries to match both m a against the type of x and (a -> m b) against the type of f.
hmm, assuming that none of cases that you mentioned above happened - then decision is based on left arguement ?
@HaskellFun It's really always based on both argument types, neither of them is more important than the other. If 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.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.