The codes below looks quite clear:
do 
  x <- Just 3
  y <- Just "!"
  Just (show x ++ y)
Here the type of x is Num and y is String. (<- here is used to take actual value out of the Monad)
However, this snippet looks not so clear to me:
import Control.Monad.Instances
addStuff :: Int -> Int
addStuff = do
  a <- (* 2)
  b <- (+ 10)
  return (a + b)
What is the type of a and type of b here? It seems they act like a Num, but a <- (* 2) and b <- (+ 10) looks cryptic here...
Does anyone have ideas about this?
                        
Well, you've stumbled upon a kind of weird monad.
The monad in question is the
Monad ((->) r). Now, what does that mean? Well, it's the monad of functions of the formr -> *. I.e., of functions that take the same type of input.You asked what the type of
aandbare in this instance. Well, they are bothNum a => a, but that doesn't really explain much.Intuitively, we can understand the monad like this: A monadic value is a function that takes a value of type
ras input. Whenever we bind in the monad, we take that value and pass it to the bound function.I.e., in our
addStuffexample, if we calladdStuff 5, thenais bound to(*2) 5(which is10), andbis bound to(+10) 5(which is15).Let's see a simpler example from this monad to try to understand how it works precisely:
If we desugar this to a bind, we get:
Now, this doesn't help much, so let's use the definition of bind for this monad:
This reduces to
Which we using the definition that
returnisconst, can reduce toWhich is a function, that multiplies a number by 2, and then adds 5.
That's one weird monad.