Reputation: 13908
This is a function I'm trying to write:
missingNumber :: (Num a) => [a] -> a
missingNumber list = (sum refList) - (sum list)
where refList = [1..n]
n = length list
Given a list of numbers, I want to sum them and compare them to a known list to see if any are missing. This code seems straightforward, but when I run it I get this (rather verbose) error:
Could not deduce (a ~ Int)
from the context (Num a)
bound by the type signature for missingNumber :: Num a => [a] -> a
at missingnumber.hs:1:18-36
`a' is a rigid type variable bound by
the type signature for missingNumber :: Num a => [a] -> a
at missingnumber.hs:1:18
Expected type: [a]
Actual type: [Int]
In the first argument of `sum', namely `refList'
In the first argument of `(-)', namely `(sum refList)'
In the expression: (sum refList) - (sum list)
I'm guessing this is happening because n
in [1..n]
must be an instance of the Enum
type class in order to be iterated over in sequence. But (assuming I'm correct), how do I cast a
as two types? Also... shouldn't Int
be a member of the Num class?
Upvotes: 0
Views: 69
Reputation: 52300
as you asked this should work:
missing :: (Num a, Foldable t) => t a -> a
missing xs = fromIntegral (sum [1..length xs + 1]) - sum xs
but only if your list of numbers is just missing one number in [1..m]
for some m
your version don't work because you claim
missingNumber :: (Num a) => [a] -> a
and then it needs to work for all Num a
- for example Double
- but then you will mix Int
with Double
(for example) - which you cannot do
fromIntegral
saves you here because it will bring back your Int
into any Num a
you might have there (it's fromIntegral :: (Integral c, Num d) => c -> d
- here you have c ~ Int
and d ~ a
- where ~
means type-equality)
Upvotes: 1