将字符串解析为数据类型:更好的错误消息?
Parsing string into data type : better error messages?
目前我正在使用以下方法将字符串解析为数据类型
来自 Text.Read
的 read
函数,如
下面的例子:
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}}
但是错误信息不是很好。例如,如果
我通过 x = 4.3
不小心把 x
变成了 Double
然后我
得到下面程序中显示的错误消息:
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
haskell 中是否有功能允许我
执行上述操作但错误消息更好?
如果你只想要更优雅的错误处理,你可以使用
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"
对于更严重的错误处理,我会使用像 parsec 这样的合适的解析库。 Parsec 提供 <?>
运算符来用有用的错误消息装饰解析器:例如如果发生解析错误,myParser <?> "foo"
将生成诸如 "expected foo" 的消息。
目前我正在使用以下方法将字符串解析为数据类型
来自 Text.Read
的 read
函数,如
下面的例子:
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}}
但是错误信息不是很好。例如,如果
我通过 x = 4.3
不小心把 x
变成了 Double
然后我
得到下面程序中显示的错误消息:
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
haskell 中是否有功能允许我 执行上述操作但错误消息更好?
如果你只想要更优雅的错误处理,你可以使用
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"
对于更严重的错误处理,我会使用像 parsec 这样的合适的解析库。 Parsec 提供 <?>
运算符来用有用的错误消息装饰解析器:例如如果发生解析错误,myParser <?> "foo"
将生成诸如 "expected foo" 的消息。