New guy at haskell here. I'm trying to get better at writing type signatures and this simple one doesn't want to work. I'm wondering why:
average :: Num a => [a] -> a
average ns = sum ns `div` length ns
Average should take any number and return some number. However I get the error
test.hs 11:27:
Couldn't match expected type 'a' with actual type 'Int'
'a' is a rigid type variable bound by
the type signature for average :: Num a => [a] -> a
at test.hs:10:12
Relevant bindings include
ns:: [a] (bound at test.hs:11:9)
average :: [a] -> a (bound at test.hs:11:1)
In the second argument of 'div' namely 'length ns'
In the expression: sum ns `div ` length ns
It seems to be saying length isn't getting what it's expecting. Can anyone help?
ok this will work:
average :: Integral a => [a] -> a
average ns = sum ns `div` (fromIntegral $ length ns)
please note that div :: Integral a => a -> a -> a
so you need Integral a
instead of just Num a
(which has no division)
And because length
will return an Int
so you need the fromIntegral
to work around it.