-1

I have a data type that goes:

BinHeap a = [BinTree a]

BinTree a = Node a i (BinHeap a)

I want a function to go through a Bintree a and give me the smallest 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

And it crashed. And i do not know why. Because the function within fold1 outputs a BinTree, therefore it should not crash.

Thank you for your time

Daniel Hernandez
  • 635
  • 1
  • 11
  • 22
  • Can you explain what "and it crashed" means? Did you get a specific error message? Does it work for some inputs but not others? etc. – Adam Wagner Jan 09 '14 at 23:31
  • `foldl1` requires the input list is non-empty, so if the heap is empty you will get an exception. – Lee Jan 09 '14 at 23:35
  • do you have `type BinHeap a = [BinTree a]` or just `BinHeap a = [BinTree a]` ? – wit Jan 09 '14 at 23:56

2 Answers2

2

Your data type says BinTree which seems to imply 'binary tree' but it isn't defined as a binary tree. It isn't even valid syntax, so I'm not quite sure what your data type is (is BinHeap a type or data? Why are there two datatypes, instead of one datatype and 2 constructors?)

If you use foldl1 on a list of BinTree a then your output will be BinTree a, not a. The correct type signature is extractMin :: Ord a => BinHeap a -> BinTree a .

The function smaller already exists, it is called min.

The most idiomatic way is probably to use Data.Foldable which will automatically give you minimum for a Foldable instance.

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
user2407038
  • 14,400
  • 3
  • 29
  • 42
0

I cannot tell what is wrong with your code, but I can see two possibilities:

  • The type parameter (a) does not have a constraint that it implement Ord. Therefore, you cannot compare them in the smaller function.

  • The lambda expression that you are passing to foldl1 should be in parentheses. Otherwise, the compiler understands that it runs to the end of the line.

Arthur Laks
  • 524
  • 4
  • 8