Search code examples
haskellbindmonadsio-monad

Haskell: Confused about type of `>>=` operator


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?


Solution

  • 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 ()