2010-12-13 70 views
19

仍在学习哈斯克尔,我实在看不出树木在Haskell

data Tree a = Leaf a | Branch [Tree a] 

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

什么是最好根据你之间的区别?这两种写作方式的含义是什么?

回答

52

第一个分支包含树的列表,因此可能包含任意数量的子树。第二个是明确的两个子树,因此是二叉树。

8

前者定义了一棵树,其中每个分支可以有任意多个子树(表示为树列表),而后者定义了一棵树,其中每个分支恰好具有两棵子树。

换句话说,前者是一般树,后者是二叉树。

那么选择哪一个取决于您是要对一般树还是二叉树进行建模。

+0

好的,但在这两种情况下,叶和分支都是由语言定义的,我定义了我自己的类型树。不是吗? – 2010-12-13 17:57:34

+3

@Stephane:不需要。在这两种情况下,既没有先前存在'Tree'类型也没有构造函数'Leaf'和'Branch',并且用'data'定义来定义它们全部三个。 – sepp2k 2010-12-13 17:59:08

+3

嗨sepp2k-问题中定义的“一般树”通常被称为玫瑰树。有时候,它们是通过一个单独的Leaf构造函数实现的 - 有时按照Data.Tree的方式,Branch构造函数携带数据。 – 2010-12-13 19:17:00

6

我已经把这个作为一个答案,而不是评论,因此有一定的格式:

data Rose a = Branch a [Rose a] 
    deriving (Show) 


sample1 :: Rose Int 
sample1 = Branch 1 [Branch 2 [], Branch 3 [Branch 5 []], Branch 4 []] 

这是一样的库模块Data.Tree,虽然Data.Tree采用现场标签和一个键入同义词。

我已经看到这棵树和你的第一个定义叫做“玫瑰树”,虽然它们有稍微不同的形状,所以术语似乎并不完全精确。我的解释是,它是嵌入在单个递归构造函数中的列表“[Rose a]”,它将其定义为玫瑰树。