Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I get an Could not deduce (Ord a) error?

Tags:

haskell

I am trying to find the list with the smallest sum of elements.:

shortest :: (Num a) => [[a]] -> [a]
shortest [] = []
shortest (x:xs) = if sum x < sum (shortest xs) then x else shortest xs

That gives me the following error:

Could not deduce (Ord a) arising from a use of `<'
from the context (Eq a)
  bound by the type signature for shortest :: Eq a => [[a]] -> [a]
  at code.hs:(8,1)-(9,71)
Possible fix:
  add (Ord a) to the context of
    the type signature for shortest :: Eq a => [[a]] -> [a]
In the expression: sum x < sum (shortest xs)
In the expression:
  if sum x < sum (shortest xs) then x else shortest xs
In an equation for `shortest':
    shortest (x : xs)
      = if sum x < sum (shortest xs) then x else shortest xs

Why doesn't the function typecheck?

like image 276
foFox Avatar asked Oct 21 '12 23:10

foFox


1 Answers

There are two type classes involved in this code: Num and Ord. Note that a type can be a member Num and not Ord, and vice versa.

The type of sum is Num a => [a] -> a so the input elements to shortest needs to be a member of Num. You also do the following in your code:

sum x < sum (shortest xs)

This means that you are using the operator < on as, but in your type signature you have not required that the as be an instance of Ord which defines <:

class Eq a => Ord a where
  compare :: a -> a -> Ordering
  (<) :: a -> a -> Bool
  ...

Therefore you need to add that requirement to your type signature:

shortest :: (Ord a, Num a) => [[a]] -> [a]

Or you could leave out the type signature.

like image 171
HaskellElephant Avatar answered Sep 20 '22 08:09

HaskellElephant