将数据类型转换为字符串以显示,而不显示“show”

问题描述 投票:3回答:2

这个问题让我非常困惑。目标是获取特定数据类型并使用它来创建字符串。数据类型是:

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的情况下为数据类型做到这一点。我合理地不知道要走哪条路。

haskell
2个回答
3
投票

你快到了!为了防止来自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...

1
投票

您可以禁用show定义的Show方法:

import Prelude hiding (show)

或者您可以明确地引用模块中定义的show。假设它是在Main中定义的,

main = putStrLn $ Main.show (Val 3)
© www.soinside.com 2019 - 2024. All rights reserved.