Long Thai
Long Thai

Reputation: 817

Could not deduce (Eq i) arising from the literal ‘0’

I'm very new to Haskell and trying to write a function that similar to take, i.e. return a specified number of items from the specified list. My code is as following:

take' :: (Num i, Ord a) => i -> [a] -> [a]
take' 0 _ = []
take' _ [] = []
take' n (x:xs) = x : take' (n - 1) xs

However, when I try to compile it, I receive the following error:

Could not deduce (Eq i) arising from the literal ‘0’
from the context (Num i, Ord a)
  bound by the type signature for
             take' :: (Num i, Ord a) => i -> [a] -> [a]
  at recursion.hs:1:10-42
Possible fix:
  add (Eq i) to the context of
    the type signature for take' :: (Num i, Ord a) => i -> [a] -> [a]
In the pattern: 0
In an equation for ‘take'’: take' 0 _ = []

I think that the error is caused as Haskell is not able to recognise 0 as a member of class type Num, but I'm not sure. Can anyone explain the error to me and show me how to fix it.

Upvotes: 2

Views: 2791

Answers (1)

Daniel Wagner
Daniel Wagner

Reputation: 153102

Pattern matches against literal numbers desugar to equality checks. So

take' 0 _ = []

becomes

take' x _ | x == 0 = []

(where x is chosen to be a variable not mentioned anywhere else in the clause). So to support this pattern, you need the number of things to take not just to be a Num but also to support (==)! That's what this part of the error says:

Could not deduce (Eq i) arising from the literal ‘0’
In the pattern: 0
In an equation for ‘take'’: take' 0 _ = []

You can just take the fix that GHC suggests in the error:

Possible fix:
  add (Eq i) to the context of
    the type signature for take' :: (Num i, Ord a) => i -> [a] -> [a]

Thus:

take' :: (Eq i, Num i, Ord a) => i -> [a] -> [a]

Afterwards you can think about whether the Ord a constraint is needed at all. =)

Upvotes: 11

Related Questions