Learn You a Haskell讨论了以下数据类型:
data Day = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday
deriving (Eq, Ord, Show, Read, Bounded, Enum)
本书演示了如何使用read
将字符串解析为Day
类型。
$ read "Saturday" :: Day
Saturday
但是,我可以传入非Day值,导致异常。
$ read "foo" :: Day
*** Exception: Prelude.read: no parse
在上面的示例中,使用read
的类型安全方式是什么?
答案 0 :(得分:12)
除了@JonPurdy提到的旧标准功能reads
之外,还有最近添加的
Text.Read.readMaybe :: Read a => String -> Maybe a
当字符串只包含一个要解析的值时,它更容易使用。
答案 1 :(得分:10)
您可以使用reads
,它会为您提供一组已解析的值和未解析的余数:
reads :: Read a => ReadS a
type ReadS a = String -> [(a, String)]
现在你可以明确地匹配结果并做你喜欢的事情:
case reads x of
-- foo
[] -> Left "no parse"
-- Saturday
[(day, "")] -> Right (day :: Day)
-- Fridayum
[(_, junk)] -> Left $ "day followed by extra junk: " ++ junk
_ -> Left "ambiguous parse"
虽然老实说我估计GHC运行时的例外成本会降低......
对于更复杂的事情,您可以使用(例如)Parsec:
编写解析器day :: Parser Day
day = choice
[ Monday <$ string "Monday"
, ...
] <* eof
无论你选择哪个解析库,都会有运行解析器和处理解析错误的方法,比如Parsec的parse
。