s-expr 打印功能中的错误

发布于 2024-10-21 09:13:20 字数 1715 浏览 6 评论 0原文

为了练习我的 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 的表示形式,以包含 NilPair 构造函数而不是 < 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

葮薆情 2024-10-28 09:13:20

我发现自己:

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

应该是

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

I found out myself:

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

should have been

showsVal (Pair x y)  =  ("(" ++) . showsPair x y . (")" ++)
                                                --  ^^^^^^
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文