Sorting 将值插入Haskell中的有序树

Sorting 将值插入Haskell中的有序树,sorting,haskell,insert,tree,Sorting,Haskell,Insert,Tree,基本上,我定义了一个树数据类型,定义如下: data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a) deriving (Eq, Ord, Show) 现在我必须创建一个函数,将值插入到有序树中(它不必对树进行排序,只需添加值)。这就是我到目前为止的想法: insert :: a -> Tree a -> Tree a insert x Empty = Leaf x insert x (Leaf m) | m &l

基本上,我定义了一个树数据类型,定义如下:

data Tree a = Empty
| Leaf a
| Node (Tree a) a (Tree a)
deriving (Eq, Ord, Show)
现在我必须创建一个函数,将值插入到有序树中(它不必对树进行排序,只需添加值)。这就是我到目前为止的想法:

insert :: a -> Tree a -> Tree a
insert x Empty      = Leaf x
insert x (Leaf m)   | m < x     = Node (Leaf x) m Empty
                    | otherwise = Node Empty m (Leaf x)
insert x (Node l m r)   | x > m     = Node (Leaf l) m (insert x r)
                        | otherwise = Node (insert x l) m (Leaf r)
insert::a->Tree a->Tree a
插入x空=叶x
插入x(叶m)| mm=节点(叶l)m(插入x r)
|否则=节点(插入x l)m(叶r)
但是,当我运行此命令时,会收到以下错误消息:

无法匹配预期的类型“a”(刚性变量) 针对推断类型“树a” “a”受Main处“insert”的类型签名约束。hs:11:10 在“Leaf”的第一个参数中,即“l” 在'Node'的第一个参数中,即'Leaf l' 在表达式中:节点(叶l)m(插入x r)

我认为这与类型有关,但我看不出我在哪里放置了任何不应该存在的类型。

你的问题是

insert x (Node l m r)   | x > m     = Node (Leaf l) m (insert x r)
                        | otherwise = Node (insert x l) m (Leaf r)
应该是

insert x (Node l m r)   | x > m     = Node l m (insert x r)
                        | otherwise = Node (insert x l) m r

因为
l
r
已经是树了。

l
节点的第一个参数,因此它属于
树a
(整个左子树)类型<另一方面,code>Leaf
只接受单个值作为参数,而不是整个树。因此,
Leaf l
给出了一个类型错误,因为它试图从整个树中生成一片叶子。也许你只是想要
l
而不是
Leaf l


另外,
Leaf x
Node Empty x Empty
之间有什么区别?您确定需要两个构造函数吗?

大致将类型检查器ese翻译成英语:

无法匹配预期的类型“a”(a 刚性变量)

这意味着它需要一个任意类型
a
,它也在其他地方使用(因此“刚性”),所以它不能只接受任何旧类型

针对推断类型“树a”

这意味着它找到了一个
,其中包含预期刚性多态类型的元素。这显然没有道理,所以它抱怨道

“a”受Main处“insert”的类型签名约束。hs:11:10

这只是说该类型受到限制,因为您在该类型签名中指定了它

在'Leaf'的第一个参数中,即第一个参数中的'l' “Node”的参数,即表达式中的“(叶l)”:Node(叶l)m(插入x r)

这只是告诉你它在抱怨哪一个特定的术语,有一些上下文

因此,要解决问题:变量
l
是一个
树a
,用于只需要
a
的上下文中。在本例中,
l
显然具有正确的类型,因此错误在于如何使用它。为什么类型检查器要查找类型
a
?因为您对它应用了
数据构造函数。但是等等,
l
已经是一个
树a
!瞧,天平从我们的眼睛上掉下来,真理被看到了


…这只是一种冗长的方式来解释为什么爱德华·科米特的快速绘制答案是正确的,以及人们可能会用什么样的推理来得出这样的答案。

本瓦德可能还想考虑插入树中已有值的行为。在上面的代码中,当一个值已经存在于叶子中的树中时,与它存在于节点中时的区别是什么?“给一个人一条鱼,你喂他一天;教一个人钓鱼,你喂他一辈子”。回答得好!