s-expr 打印功能中的错误
为了练习我的 Haskell 技能,我遵循自己编写一个方案教程。我已经实现了 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
的表示形式,以包含 Nil
和 Pair
构造函数而不是 < code>List 和 DottedList
,因为它们与 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
中,但我就是无法弄清楚。
To practice my Haskell skills, I'm following the Write Yourself a Scheme tutorial. I've implemented a parser for s-expressions, but I'm having trouble with the printing function.
When I run the following program
main :: IO ()
main = do args <- getArgs
putStrLn $ readExpr (args !! 0)
it parses the s-expressions correctly, but when I define my own shows
instead of deriving
it, I get erroneous output for nested lists and lists inside vectors:
$ ./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))))
Other cases and nested vectors work fine, though:
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))
I've changed the representation of LispVal
to include Nil
and Pair
constructors instead of List
and DottedList
, as these match better with the Scheme data model. Printing lists is done by
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
I suspect the error is in showsPair
, but I just can't figure it out.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我发现自己:
应该是
I found out myself:
should have been