interactEither
interact
is a very handy function, but it doesn’t handle computations that can fail. Here’s another convenience function that addresses that:
import System.IO
import System.Exit
interactEither :: Show a => (String -> Either a String) -> IO ()
interactEither f = getContents >>= either (error . show) success . f
where success x = hPutStrLn stdout x >> exitSuccess
error x = hPutStrLn stderr x >> exitFailure