Search code examples
haskellioparsec

Haskell: Parsing a file with Parsec and IO


So I'm still trying to get comfortable using Parsec, but I'm slowly working it into my toolbox.

When I have a file I need to parse, I find myself reading the file in as a string, and then passing the contents to parsec:

problem <- readFile input                               
case runParser myParser () input problem of
  Left err  -> hPutStrLn stderr $ "Error: " ++ show err 
  Right cs  -> -- continue processing...

This seems like a fairly common pattern though - is there some existing function that I can use that takes a ParsecT String u IO a and a FilePath and parses the contents? I can't find anything in hoogle, but that might just be a failure of imagination.


Solution

  • Not ParsecT, but there's parseFromFile:: Parser a -> String -> IO (Either ParseError a). However, if your code snippet is accurate, you don't actually need the IO in your parser, so this shouldn't be a problem. Something like this should produce the behaviour you want:

    import Text.Parsec.String
    import System.Exit
    import System.IO
    
    parse :: Parser a -> String -> IO a
    parse p fileName = parseFromFile p fileName >>= either report return
      where
        report err = do
            hPutStrLn stderr $ "Error: " ++ show err
            exitFailure
    

    It's still a little verbose, but you can define report somewhere common and use it throughout your program; then parse is a one-liner.