I'm working my way through some introductory Haskell materials and am currently going through Monads. I conceptually understand that the >>=
operator is of type:
(Monad m) => m a -> (a -> m b) -> m b
.
In that context, I'm confused as to why the following code works, i.e., why it doesn't result in a type mismatch:
main = getLine >>= \xs -> putStrLn xs
Since we know that getLine :: IO String
, I'd assume that it can be 'bound' with a function of type String -> IO String
. However putStrLn
is of a different type: putStrLn :: String -> IO ()
.
So why does Haskell allow us to use >>=
with these two functions?
Let's just line up the types:
(>>=) :: m a -> ( a -> m b) -> m b
getLine :: IO String
putStrLn :: (String -> IO ())
Here we have m = IO
, a = String
, and b = ()
, so we can substitute these into >>=
's type signature to get a final type signature of
(>>=) :: IO String -> (String -> IO ()) -> IO ()