I’m trying to write a program in Haskell
that gets a list (of integer) and prints out the number of elements that are bigger than the list’s average
So far I tried
getAVG::[Integer]->Double
getAVG x = (fromIntegral (sum x)) / (fromIntegral (length x))
smallerThanAVG:: [Integer]->Integer
smallerThanAVG x = (map (\y -> (if (getAVG x > y) then 1 else 0)) x)
For some reason I’m getting this error
Couldn't match expected type `Double'
against inferred type `Integer'
Expected type: [Double]
Inferred type: [Integer]
In the second argument of `map', namely `x'
It could be that I haven’t written the logic correctly, although I think I did..
Ideas?
These errors are the best kind, because they pinpoint where you have made a type error.
So let’s do some manual type inference. Let’s consider the expression:
There are a few constraints we know off the bat:
Now let’s look at the larger expressions.
Now let’s work backwards.
expr5is the same as the RHS ofsmallerThanAVG, so that means it has the same result type as what you’ve declared.However, this doesn’t match our other constraint: the result of
mapmust be[b]for someb.Integeris definitely not a list (although if you get facetious, it could be coerced into a list of bits). You probably meant tosumthat list up.Now let’s work forwards.
Herein lies the conflict:
ycannot be both aDoubleand anInteger. I could equivalently restate this as:xcannot be both a[Double]and[Integer], which is what the compiler is saying. So tl;dr, the kicker is that(>)doesn’t compare different types ofNums. The meme for this sort of problem is: “needs morefromIntegral“.