Haskell: obfuscated type of `>> =` operator
I am working on some introductory Haskell stuff and am currently reviewing Monads. I understand conceptually that the operator >>=
is of type:
(Monad m) => m a -> (a -> m b) -> m b
...
In this 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 would guess that it can be "associated" with a function of the type String -> IO String
. However, putStrLn
a different type: putStrLn :: String -> IO ()
.
So why does Haskell allow us to use >>=
with these two functions?
source to share
Let's just align 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 replace them with a type signature >>=
to get the final type signature
(>>=) :: IO String -> (String -> IO ()) -> IO ()
source to share
Since we know that
getLine :: IO String
, I would guess that it can be "associated" with a function of the typeString -> IO String
.
Why do you think so? Look again at the type signature:
(>>=) :: m a -> (a -> m b) -> m b
The thing on the left is m a
, the thing on the right is m b
. Specifically, the bit in the middle a -> m b
,,, says that the function you are passing to >>=
takes a
and returns m b
. It doesn't say what it should return m a
, it says it can be m b
, where b
is any random type. It doesn't have to match a
.
In your example, the lambda function takes String
and returns IO ()
. So, a = String
and b = ()
. And that's great.
source to share