artella
artella

Reputation: 5118

Parsing string into data type : better error messages?

Currently I am parsing strings into data types using the read function from Text.Read as shown in the example below :

module Main where

data Inner = Inner { x :: Int , y :: Double } deriving (Read,Show)
data Outer = Outer { inner :: Inner } deriving (Read,Show)

parseOuter :: Outer
parseOuter = read "Outer { inner = Inner { x = 4, y = 4.5 } }"

main = do
  print parseOuter
  --output : Outer {inner = Inner {x = 4, y = 4.5}}

However the error messages are not very good. For example if I accidentally make x a Double by doing x = 4.3 then I get the error message shown in the program below :

module Main where

data Inner = Inner { x :: Int , y :: Double } deriving (Read,Show)
data Outer = Outer { inner :: Inner } deriving (Read,Show)

parseOuter :: Outer
parseOuter = read "Outer { inner = Inner { x = 4.3 , y = 4.5 } }"

main = do
  print parseOuter
  --output : *** Exception: Prelude.read: no parse

Is there functionality in haskell which would allow me to do the above but with better error messages?

Upvotes: 2

Views: 115

Answers (1)

chi
chi

Reputation: 116139

If you only want a more graceful error handling, you can use

import Text.Read

parseOuter :: Maybe Outer
parseOuter = readMaybe "Outer { inner = Inner { x = 4, y = 4.5 } }"

main :: IO ()
main = do
  case parseOther of
    Just x  -> print x
    Nothing -> putStrLn "parse error"

For more serious error handling, I'd use a proper parsing library like parsec. Parsec provides the <?> operator to decorate the parser with helpful error messages: e.g. myParser <?> "foo" will generate messages such as "expected foo" if a parse error occurs.

Upvotes: 1

Related Questions