I want a function that calculates average mark from a given list of marks. This is what I have made so far:
getAverageRate :: [Int]->Int
getAverageRate marks = (fromIntegral (foldr (+) 0 marks))/(fromIntegral (length marks))
What I am trying to do is to get the sum of all marks in the list by using 'foldr' then divide by 'length marks'. Despite I already use 'fromIntegral' this error still appears and I can not find the problem.
No instance for (Fractional Int) arising from a use of `/'
Possible fix: add an instance declaration for (Fractional Int)
In the expression:
  (fromIntegral (foldr (+) 0 marks)) / (fromIntegral (length marks))
In an equation for `getAverageRate':
    getAverageRate marks
      = (fromIntegral (foldr (+) 0 marks))
        / (fromIntegral (length marks))
                The thing is that Int represents an integer, so it doesn't make sense to be able to divide it since most divisions result in things which aren't integers.
Happily we have div, which is integer division, so you could do
 average :: [Int] -> Int
 average [] = error "Can't average an empty list"
 average xs = sum xs `div` length xs
If you don't want to use integer division, then we could do something like
 average :: [Int] -> Double
 average xs = fromIntegral (sum xs) / fromIntegral (length xs)
which just promotes everything to a Double for division.
Finally you could choose a method for rounding and go with what you have
 average xs = round $ fromIntegral (sum xs) / fromIntegral (length xs)
(Friendly neighborhood warning that sum is evil and uses foldl instead of foldl' so be sure to compile with -O2 when using long lists)
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