1
votes

I'm a beginner in Haskell and have a trouble in the next block:

up_heap :: Num a => [a] -> [a] -> [a]
up_heap heap (h:t) =
let ppos = quot (length heap) 2 in
        case ((ppos > 0) && ((heap !! ppos) > h)) of
            True ->
                let (upper, (p:lower)) = splitAt ppos heap in
                    up_heap upper (h:lower) ++ (p:t)
            False ->
                heap ++ h:t

Next error: Could not deduce (Ord a) arising from a use of `>'

How improve this?

2

2 Answers

6
votes

You are using > on an element of heap which is of type Num a => a (the element). > is part of the Ord typeclass and as you could see in the documentation (http://hackage.haskell.org/packages/archive/base/3.0.3.1/doc/html/GHC-Num.html), a type implementing Num does not necessarily implement Ord.

class (Eq a, Show a) => Num a where

Add a constraint in your type signature like (Num a, Ord a) => ....

1
votes

I'm a beginner too. I've been making a little chart as I go along, which might be helpful to you:

Eq   -- specifies the functions: (==) (/=)  
        Also, a required typeclass for a variable if:  
            1) you check to see if a variable is in a list with the `elem` list function
            2) a variable is being pattern matched against a specific value
            3) you pass a variable to another function that requires its arg to be (Eq a)

Ord  -- specifies the functions: (<) (<=) (>) (>=)
            (Ord implements Eq)

Num  -- specifies the functions: (+) (-) (*) 
             but NOT (/) which is part of the Fractional typeclass
             (Num implements Show, Eq)

             ghci> :t (*)
             (*) :: (Num a) => a -> a -> a

Integral   -- specifies the functions: mod, div(integer division operator)                
                 Both Int and Integer(= really big ints) implement the 
                 Integral typeclass
                 (Integral implements Real(which implements both Ord and Num) )

Fractional -- specifies the function: (/)
                 Float, Double, Rational types implement Fractional
                 (Fractional implements Num)

When I first write my type declarations, I don't worry too much about the 'type constraints' I might need, so I might write:

myfunc :: a -> a -> a

Then after I write the function, I look around the function, and I identify what operators are being used on the a's. If a's are being added, I look at the chart and see that Num is the typeclass that has the (+) operator. If a's are being compared with <, then I look at the chart and see that Ord has the comparison operators. At that point, I add stuff to the type declaration to make sure all the necessary typeclasses are specified:

myfunc :: (Num a, Ord a) => a -> a -> a

The type 'a' stands for any type, and the type constraints, (Num a, Ord a), say, "Hold on there, not any type will do for 'a'. There's going to be some adding and comparing done with those a's, so the type of 'a' is restricted from being any type to a type that implements the functions in Num and Ord.