【问题标题】:Bug in s-expr printing functions-expr 打印功能中的错误
【发布时间】:2011-03-10 14:37:32
【问题描述】:

为了练习我的 Haskell 技能,我正在学习 Write Yourself a Scheme 教程。我已经为 s 表达式实现了一个解析器,但是我在打印功能上遇到了问题。

当我运行以下程序时

main :: IO ()
main  =  do args <- getArgs
            putStrLn $ readExpr (args !! 0)

它正确解析了 s 表达式,但是当我定义自己的 shows 而不是 deriving 它时,我会得到嵌套列表和向量内列表的错误输出:

$ ./parser "(1 (2) 3)"
(1 (2 3))
$ ./parser "#(1 (2) 3)"
#(1 (2 3))
$ ./parser "(1 (2 (3)) 4)"
(1 (2 (3 4)))
$ ./parser "(1 (2 (3)) (4))"
(1 (2 (3 (4))))

不过,其他情况和嵌套向量也可以正常工作:

lars@zygmunt:~/src/scm48$ ./parser "(1 #(2) 3)"
(1 #(2) 3)
lars@zygmunt:~/src/scm48$ ./parser "#(1 #(2) 3)"
#(1 #(2) 3)
lars@zygmunt:~/src/scm48$ ./parser "(1 (2 3))"
(1 (2 3))

我已更改 LispVal 的表示形式,以包含 NilPair 构造函数,而不是 ListDottedList,因为它们与 Scheme 数据模型更匹配。打印列表由

完成
showsVal :: Value -> ShowS
showsVal Nil              =  ("()" ++)
showsVal (Pair x y)       =  ("(" ++) . showsPair x y . (++ ")")
showsVal (String s)       =  shows s
showsVal (Symbol n)       =  (n ++)
showsVal (Number x)       =  shows x
showsVal (Boolean True)   =  ("#t" ++)
showsVal (Boolean False)  =  ("#f" ++)
showsVal (Vector v)       =  ("#(" ++) . showsVec v . (")" ++)

showsPair x Nil         =  showsVal x
showsPair x (Pair y z)  =  (showsVal x) . (" " ++) . showsPair y z
showsPair x y           =  (showsVal x) . (" . " ++) . (showsVal y)

showsVec []      =  id
showsVec [x]     =  shows x
showsVec (x:xs)  =  shows x . (" " ++) . showsVec xs

我怀疑错误在showsPair,但我就是想不通。

【问题讨论】:

  • 嗯。你怎么知道解析是正确的?
  • 像之前的评论一样:您同时测试解析器和打印机:为什么不制定单独的测试用例来查看哪个包含错误?
  • @ephemient:我知道解析是正确的,因为当我使用 deriving Show 时,它会以 Haskell 表示法打印正确的结构。

标签: haskell lisp scheme s-expression


【解决方案1】:

我发现了自己:

showsVal (Pair x y)  =  ("(" ++) . showsPair x y . (++ ")")

应该是

showsVal (Pair x y)  =  ("(" ++) . showsPair x y . (")" ++)
                                                --  ^^^^^^

【讨论】:

  • 如果你使用showStringshowChar,你可以避免这个问题,例如:showsVal (Pair x y) = showChar '(' . showsPair x y . showChar ')' - 甚至还有一个 showParens 函数让它更简单。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-26
  • 2013-10-21
  • 1970-01-01
相关资源
最近更新 更多