我有一个数据类型:
BinHeap a = [BinTree a]
BinTree a = Node a i (BinHeap a)
我想要一个函数通过Bintree a并给我最小的a。
extractMin :: BinHeap a -> a
extractMin ps
= foldl1 (\(Node x y z) (Node x' y' z') -> Node (smaller x x') y z) ps
where
smaller x y = if x <= y then x else y
它崩溃了。同时我不知道为什么。因为fold1中的函数输出BinTree,所以它不应该崩溃。
感谢您的时间
答案 0 :(得分:2)
您的数据类型显示BinTree
,这似乎意味着“二叉树”,但它没有被定义为二叉树。它甚至不是有效的语法,所以我不太确定你的数据类型是什么(BinHeap
是type
还是data
?为什么有两种数据类型,而不是一种数据类型和2个构造函数?)
如果您在foldl1
列表中使用BinTree a
,那么您的输出将是BinTree a
,而不是a
。正确的类型签名是extractMin :: Ord a => BinHeap a -> BinTree a
。
函数smaller
已存在,称为min
。
最惯用的方式可能是使用Data.Foldable
,它会自动为minimum
个实例提供Foldable
。
import Data.Foldable
import Prelude hiding (minimum)
import Data.Monoid
data Tree a = Tree a [Tree a] | Leaf
instance Foldable Tree where
-- foldMap :: Monoid m => (a -> m) -> Tree a -> m
foldMap _ Leaf = mempty
foldMap f (Tree a xs) = f a `mappend` mconcat (map (foldMap f) xs)
minTree :: Ord a => Tree a -> a
minTree = minimum
答案 1 :(得分:0)
我不知道你的代码有什么问题,但我可以看到两种可能性:
类型参数(a)没有实现Ord
的约束。因此,您无法在较小的函数中对它们进行比较。
传递给foldl1的lambda表达式应该在括号中。否则,编译器会理解它运行到行尾。