我在Haskel中有一个二进制搜索树的插入函数。我的插入函数前两行看起来像这样
insert :: (Ord a) => BST a -> a -> BST a
insert Nil x = Node x Nil Nil
我知道这个功能有效,我已经在单个数字上测试了它。但现在我正在尝试将插入应用于列表。我试过这段代码
let mBST = foldr insert Nil [1,2,7,9,3,5]
我收到以下错误
Occurs check: cannot construct the infinite type: a0 = BST a0
Expected type: BST (BST a0) -> BST a0 -> BST a0
Actual type: BST (BST a0) -> BST a0 -> BST (BST a0)
In the first argument of `foldr', namely `insert'
In the expression: foldr insert Nil [1, 2, 7, 9, ....]
我在BST中出现错误a - > a - > BST但我不知道如何解决它。
答案 0 :(得分:4)
foldr
具有类型(a -> b -> b) -> b -> [a] -> b
,这意味着它需要类型为a -> b -> b
的函数作为其第一个参数。在您的特定示例中,转换为Integer -> BST Integer -> BST Integer
,这与插入的类型不同。
最简单的解决方案是翻转插入功能:
let mBST = foldr (flip insert) ...
答案 1 :(得分:2)
原因是foldr f init lst
传递f
列表中的元素以及按顺序折叠列表的其余部分的结果。你可以写
insert :: (Ord a) => a -> BST a -> BST a
insert x Nil = Node x Nil Nil
(这可能更惯用)或写foldr (flip insert) Nil
。
正如您可能很快就会知道的那样,在这种情况下使用严格的左侧折叠而不是右侧折叠会更有效。使用您的实现,这是foldl' insert Nil
。使用我的(更惯用的),foldl' (flip insert) Nil
。