【发布时间】:2013-07-24 06:22:49
【问题描述】:
总的来说,我对 Haskell 和函数式编程还是很陌生,所以我正在用 Parsec 编写一个小程序来解析 JSON 并漂亮地打印它作为学习基本概念的一种手段。这是我目前所拥有的:
import Text.Parsec
import Text.Parsec.String
data JValue = JString String
| JNumber Double
| JBool Bool
| JNull
| JObject [(String, JValue)]
| JArray [JValue]
deriving (Eq, Ord, Show)
parseJString, parseJNumber, parseJBool, parseJNull :: Parser JValue
parseJString = do
str <- between (char '"') (char '"') (many (noneOf "\""))
return . JString $ str
parseJNumber = do
num <- many digit
return . JNumber . read $ num
parseJBool = do
val <- string "true" <|> string "false"
case val of
"true" -> return (JBool True)
"false" -> return (JBool False)
parseJNull = string "null" >> return JNull
parseJValue :: Parser JValue
parseJValue = parseJString
<|> parseJNumber
<|> parseJBool
<|> parseJNull
现在,我假设这些数字是整数。单独地,parseJString、parseJNumber、parseJBool 和 parseJNull 在 ghci 中按预期工作。此外,parseJValue 可以正确解析字符串和数字。
ghci> parse parseJString "test" "\"test input\""
Right (JString "test input")
ghci> parse parseJNumber "test" "345"
Right (JNumber 345.0)
ghci> parse parseJBool "test" "true"
Right (JBool True)
ghci> parse parseJNull "test" "null"
Right JNull
ghci> parse parseJValue "test" "\"jvalue test\""
Right (JString "jvalue test")
ghci> parse parseJValue "test" "789"
Right (JNumber 789.0)
parseJValue 失败,但是,当我尝试解析 true、false 或 null 时,我收到了一个有趣的错误。
ghci> parse parseJValue "test" "true"
Right (JNumber *** Exception: Prelude.read: no parse
我得到一个成功的解析,但是解析返回一个JNumber,后面跟着一个错误,指出 Prelude.read 失败。我觉得我在构建解析器时缺少一些核心概念,但我看不出哪里出错了。另外,我的代码是否犯了任何初学者错误,即这些是否会被视为“坏”haskell?
【问题讨论】: