这个问题让我非常困惑。目标是获取特定数据类型并使用它来创建字符串。数据类型是:
data Math = Val Int
| Add Math Math
| Sub Math Math
| Mult Math Math
| Div Math Math
deriving Show
这个例子:
ex1 :: Math
ex1 = Add1 (Val1 2) (Val1 3)
应该用正确的代码输出"2 + 3"
。
我写了下面的代码并意识到我有两个问题:
show :: Math -> String
show (Val n) = show n
show (Add e1 e2) = show e1 ++ " + " ++ show e2
show (Sub e1 e2) = show e1 ++ " - " ++ show e2
show (Mult e1 e2) = show e1 ++ " * " ++ show e2
show (Div e1 e2) = show e1 ++ " / " ++ show e2
曲线球是函数必须命名为show
,因为它是 - 所以从Prelude调用show
是行不通的。我首先想到创建一个帮助器,将每个值转换为文字但是,我再也不知道如何在没有show
的情况下为数据类型做到这一点。我合理地不知道要走哪条路。
你快到了!为了防止来自Prelude的show
干扰,请添加
import Prelude hiding (show)
到文件的顶部。
但是,毕竟你需要访问Prelude的show
,以便你可以在你的Int
中显示Val
。所以也添加这个:
import qualified Prelude (show)
有了这两行,你可以写:
show :: Math -> String
show (Val n) = Prelude.show n
show (Add e1 e2) = show e1 ++ " + " ++ show e2
show (Sub e1 e2) = show e1 ++ " - " ++ show e2
show (Mult e1 e2) = show e1 ++ " * " ++ show e2
show (Div e1 e2) = show e1 ++ " / " ++ show e2
你应该拥有你想要的东西。
或者,如果你想要实现Show
这个类而不是一个独立的,相同(并且容易混淆)命名的show
函数,那么你为show
编写的代码就像是一样。你只需要将它放在一个实例定义中,如下所示:
instance Show Math where
show (Val n) = show n
-- etc...
您可以禁用show
定义的Show
方法:
import Prelude hiding (show)
或者您可以明确地引用模块中定义的show
。假设它是在Main
中定义的,
main = putStrLn $ Main.show (Val 3)