I use it basically as the beginning of a pipe, where I want to process, for example, a String, but I have to start the pipe with an IO String.
Simplest example, I have would be to read something from a file and apply some function `f :: String -> String` to the contents of the file, and return an IO String again. Let's say that overarching function is called readFileAndProcess, then it could be defined like
Simplest example, I have would be to read something from a file and apply some function `f :: String -> String` to the contents of the file, and return an IO String again. Let's say that overarching function is called readFileAndProcess, then it could be defined like
`readFileAndProcess :: (String-> String) -> String -> IO String`
`readFileAndProcess f fileName = putStrLn . f <=< (readFile fileName)`