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.