使数据类型成为Haskell中Show的实例

nic*_*ole 11 tree haskell types instance show

我需要将以下数据类型作为以下实例Show:

data Tree a b = Branch b (Tree a b) (Tree a b) | Leaf a 
Run Code Online (Sandbox Code Playgroud)

我对此很新,但首先,我将此声明解释为

"我们创建了一个名为Tree的新类型,它使用类型a和b进行参数化.树可以是两个东西之一:一个分支,它包含一个b类型的数据,另外两个树,或一个叶子,它持有类型为a的数据项."

现在,我需要做一个很好地"展示"它(嵌套分支等)的方法,而不使用deriving.到目前为止,我只是在一个模块Main中编写函数,并在解释器窗口中加载/播放它们,所以我之前并没有实际使用构造函数等.尽管如此,我想我可以从我的文件中声明树数据类型开始,如问题开头所示,然后从那里开始.

当我用"Show"搞砸了没有太大的成功时,我想也许我需要在尝试使用整个树之前定义树的一个小组件以及如何首先"显示"它:

data Leaf a = Leaf a

instance Show (Leaf a) where
show (Leaf a) = ??? 
Run Code Online (Sandbox Code Playgroud)

我在???中尝试了很多东西?现货,比如"a",只是一个单独的,putStrLn等,但当我说出类似的东西时,没有一个打印出来的值a

>show (Leaf 3)
Run Code Online (Sandbox Code Playgroud)

事实上,我在很多情况下遇到过这种情况,这可能意味着我找不到合适的东西:

Ambiguous occurrence `show'
    It could refer to either `Main.show', defined at a2.hs:125:1
                          or `Prelude.show',
                             imported from `Prelude' at a2.hs:2:8-11
                             (and originally defined in `GHC.Show')
Run Code Online (Sandbox Code Playgroud)

...我通过调用"Main.show"来解决这个问题,当然这不起作用.

我想问题是,我在哪里可以使用所有这些...或者只是,"我如何修复Leaf"Show"实用程序,以便我可以弄清楚如何扩展它?" (假设我必须先定义它......)

Dan*_*kov 22

你必须这样开始:

data Tree a b = Branch b (Tree a b) (Tree a b) | Leaf a

instance (Show a, Show b) => Show (Tree a b) where
    show (Leaf x) = show x
    show (Branch p l r) = ???
Run Code Online (Sandbox Code Playgroud)

为了show一个Tree a b你必须首先能够show aS和b秒.这就是该(Show a, Show b) =>部分的作用,它指定了实例工作所需的前提条件.


Mat*_*hid 8

这是一个小小的暗示:通过写作

 instance Show (Leaf a) where
 show (Leaf a) = ???
Run Code Online (Sandbox Code Playgroud)

实际做的是定义一个 Show实例,然后是一个顶级show函数.这就是你得到"含糊show"错误的原因; 你已经定义了一个新show函数,其名称与现有函数冲突.

你的意思

 instance Show (Leaf a) where
   show (Leaf a) = ???
Run Code Online (Sandbox Code Playgroud)

注意第二行现在是如何缩进的.这意味着您正在重新定义现有show方法,正如您可能想要的那样.


mer*_*ict 5

最简单的答案是自动派生一个Show实例:

data Tree a b = Branch b (Tree a b) (Tree a b) | Leaf a deriving Show
Run Code Online (Sandbox Code Playgroud)

但是,让我们说这并不能为您提供所需形式的输出.如果要定义自己的Show实例,可以执行以下操作:

instance (Show a, Show b) => Show (Tree a b) where
    show (Leaf a) = "Leaf " ++ (show a)
    show (Branch b l r) = "Branch " ++ (show b) ++ " { " ++ l ++ ", " ++ r " }"
Run Code Online (Sandbox Code Playgroud)

你可能会读到第一行的方式是"给定a并且b都是Show类型类Tree a b的实例,也是Show类型类的实例......"

顺便说一句,缩进很重要.它可能在您粘贴的代码段中被破坏,但您必须showinstance声明下缩进函数定义.