It is a very general question about extracting data from monadic values.
The general idea is to use >>=
function:
main = readFile foo >>= \s -> print s
>>=
takes 2 arguments. It extracts the value from its first argument and passes it to its second argument. The first argument is monadic value, in this case of type IO String
, and the second argument is a function that accepts a plain, non-monadic value, in this case String
.
There is a special syntax for this pattern:
main = do
s <- readFile foo
print s
But the meaning is the same as above. The do
notation is more convenient for beginners and for certain complicated cases, but explicit application of >>=
can lead to a shorter code. For example, this code can be written as just
main = readFile foo >>= print
Also there are a big family of library functions to convert between monadic and non-monadic values. The most important of them are return
, fmap
, liftM2
and >=>
.
The concept of monad is very useful beyond representing IO in a referentially transparent way: these helpers are very useful for error handling, dealing with implicit state and other applications of monads.
The second most important monad is Maybe
.