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?

+3


source to share


3 answers


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

      

+14


source


()

is a valid type (called one, note that it only contains one possible non-lower value), but in the definition there will be b

.

a

= String

and b

= ()

, so we get:



IO String -> (String -> IO ()) -> IO ()

+5


source


Since we know that getLine :: IO String

, I would guess that it can be "associated" with a function of the type String -> 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.

+4


source







All Articles