Reputation: 817
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
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