Consider the following IO
code:
ghci> let x = return 100 :: IO Int
ghci> :t do { a <- x; print a; return 500 }
do { a <- x; print a; return 500 } :: Num b => IO b
My understanding of do notation/bind is that the following signature will be enforced by the compiler:
ghci> :t (>>=)
(>>=) :: Monad m => m a -> (a -> m b) -> m b
In the above example, my understanding is:
x
has typeIO Int
print a
has typeIO ()
return 500
has typeNum b => IO b
It seems to me that IO ()
does not conform to the type, Num b => IO b
. Additionally, IO Int
does not conform to Num b => IO b
, as I understand.
If this observation is valid, then why does this code compile? Must not each line, i.e. >>=
, conform to m b
, where m
equals IO and b
equals Num b => b
?