I'm playing with some Haskell code. I've defined two functions:
count :: [a] -> Int
count [] = 0
count (x:xs) = 1 + (count xs)
-- 03. Write a function that computes the mean of a list, i.e., the sum of all
-- elements in the list divided by its length. (You may need to use the
-- fromIntegralfunction to convert the length of the list from an integer
-- into a floating-point number.)
-- I've guessed this type definition, but it's incorrect:
-- listMean :: [a] -> Double
-- The following is the same inferred by hgci
listMean :: (Fractional a) => [a] -> a
listMean lst = (foldl1 (+) lst)/(fromIntegral (count lst))
Why [a] -> Double is not correct? It seems that I give lst that is a generic list of some type a and listMean returns a Double. What am I doing wrong?
Thanks, Alfredo
First of all, listMean :: [a] -> Double says that listMean is a function taking a list of any type a to a single Double value.
But you rely on being able to apply (+) to the elements of the list (foldl1 (+)), which requires that the type a be an instance of Num, which means you have at least:
listMean :: (Num a) => [a] -> b
You also apply (/) to the value of type a that results from the foldl1 operation. To do so, a must not only be an instance of Num, but of Fractional. Applying this requirement to the type a gives the type signature:
listMean :: (Fractional a) => [a] -> b
Now, what of b? Well, the signature for (/) is (/) :: (Fractional a) => a -> a -> a. So, the result of listMean must also be an instance of Fractional. Further, it must be the same instance of Fractional as that contained in the list: type b is thus, in fact, type a, and listMean's most general signature is:
listMean :: (Fractional a) => [a] -> a
This is exactly what the compiler inferred. If you want to specialize this for Double, you would have to replace both occurrences of a with Double:
listMean :: [Double] -> Double
This is because you have no operator in there that will coerce any instance of Fractional into a Double, so both input and output to (/) must be of type Double.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With