There is no way to get a value of type a
out of an expression of type IO a
and there shouldn't be. This is actually a large part of why monads are used to model IO
.
An expression of type IO a
can be thought of as representing an action that can interact with the real world and, if executed, would result in something of type a
. For example, the function getLine :: IO String
from the prelude doesn't mean that underneath getLine
there is some specific string that I can extract - it means that getLine
represents the action of getting a line from standard input.
Not surprisingly, main :: IO ()
since a Haskell program does represent a computation/action that interacts with the real world.
The things you can do to expressions of type IO a
because IO
is a monad:
Sequence two actions using (>>)
to produce a new action that executes the first action, discards whatever value it produced, and then executes the second action.
-- print the lines "Hello" then "World" to stdout
putStrLn "Hello" >> putStrLn "World"
Sometimes you don't want to discard the value that was produced in the first action - you'd actually like it to be fed into a second action. For that, we have >>=
. For IO
, it has type (>>=) :: IO a -> (a -> IO b) -> IO b
.
-- get a line from stdin and print it back out
getLine >>= putStrLn
Take a normal value and convert it into an action which just immediately returns the value you gave it. This function is less obviously useful until you start using do
notation.
-- make an action that just returns 5
return 5
More from the Haskell Wiki on the IO monad here.