[英]Inserting a value into an ordered tree in Haskell
基本上我已经定义了一个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 < 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)
但是,当我运行它时,我收到以下错误消息:
无法将预期类型'a'(刚性变量)与推断类型匹配'树a''a'受Main.hs中'insert'类型签名的约束:11:10在'Leaf'的第一个参数中,即'l'在'Node'的第一个参数中,即'(Leaf l)'在表达式中:Node(Leaf l)m(insert xr)
我认为这与类型有关,但是我看不出哪里放了任何不应该存在的类型。
你的问题是
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
已经是树。
大致从type-checker-ese翻译成英文:
无法匹配预期类型'a'(刚性变量)
这意味着它期待一个任意类型a
,它也在其他地方使用(因此“刚性”),因此它不能只采用任何旧类型。
反对推断类型'树a'
这意味着它找到了一个包含预期刚性多态类型元素的Tree
。 这显然没有意义,所以它抱怨。
'a'受Main.hs:11:10中'insert'类型签名的约束
这只是说该类型受到限制,因为您在该类型签名中指定了它。
在'Leaf'的第一个参数中,即'l'在'Node'的第一个参数中,即'(Leaf l)'在表达式中:Node(Leaf l)m(insert xr)
这只是告诉你它正在抱怨哪个特定术语,并带有一些背景信息。
因此,要解决问题:变量l
是在需要a的上下文中使用的Tree a
a
。 在这种情况下, l
显然具有正确的类型,因此错误在于如何使用它。 为什么类型检查器要查找类型a
? 因为您将Tree
数据构造函数应用于它。 但等等, l
已经是Tree a
! 瞧 ,鳞片从我们的眼睛里掉下来,真相被看到了。
......这只是解释为什么爱德华·凯梅特的快速回答是正确的,以及可能用什么样的推理来得出这样一个答案的冗长方式。
l
是Node
的第一个参数,因此它是Tree a
(整个左子树)的类型。 另一方面, Leaf
只需要一个值作为参数,而不是整个树。 因此Leaf l
给出了一个类型错误,因为它试图从整棵树中制作一个Leaf。 可能你只是想在这个地方使用l
而不是Leaf l
。
另外, Leaf x
和Node Empty x Empty
之间有什么区别? 你确定你需要两个构造函数吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.