繁体   English   中英

在Haskell中将值插入有序树中

[英]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

因为lr已经是树。

大致从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 ,鳞片从我们的眼睛里掉下来,真相被看到了。

......这只是解释为什么爱德华·凯梅特的快速回答是正确的,以及可能用什么样的推理来得出这样一个答案的冗长方式。

lNode的第一个参数,因此它是Tree a (整个左子树)的类型。 另一方面, Leaf只需要一个值作为参数,而不是整个树。 因此Leaf l给出了一个类型错误,因为它试图从整棵树中制作一个Leaf。 可能你只是想在这个地方使用l而不是Leaf l

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM