这是我正在处理的代码的简化版本
data ArithExp = Con Int
| Add ArithExp ArithExp
instance Show ArithExp where
show (Con i) = show i
show (Add e1 e2) = show "( " ++ show e1 ++ " + " ++ show e2 ++ " )"
所以,如果我运行命令
Add (Con 6) (Con 0)
我想要的输出是:
( 6 + 0 )
但上面的代码打印出来:
"( "6 + 0 )
据我所知,show函数将第一个字符串中的引号打印为字符,然后在后面的串联中正确使用它们。这种行为对我来说似乎很不一致。任何有助于我获得正确输出的见解都将非常感激。 提前谢谢!
答案 0 :(得分:10)
在(Add e1 e2)
分支show
中绑定比(++)
更紧密,因此您的代码更为合理,
show (Add e1 e2) = (show "( ") ++ (show e1) ++ " + " ++ (show e2) ++ " )"
诀窍在于你并不真正需要领先show
---你直接生成字符串,只需要show
递归地应用于e1
和{{1 }}
e2
答案 1 :(得分:0)
通常,show
会尝试打印您的数据,如果您要将其键入ghci,它将评估为等效的数据值。想想在字符串的情况下这意味着什么。如何键入字符串值,以便Haskell将其解释为字符串而不是要评估的表达式?
这是一个示例ghci会话,说明我的意思:
> let myString = "Hello"
> putStrLn $ show myString
=> "Hello"
> :t "Hello"
=> "Hello" :: String
> putStrLn myString
=> Hello
> :t Hello
=> Not in scope: data constructor 'Hello'
由于您最初必须在引号中键入字符串,以便它将计算为字符串而不是构造函数表达式,show
将在其周围加上引号,以便您可以将值粘贴回ghci并获取字符串值而不是构造函数值。
虽然show
的行为在您的示例中可能看起来有点违反直觉,但实际上它的行为方式却非常一致。希望知道它为什么这样做会帮助你避免将来遇到这样的问题!