4

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))
1
  • By calling fromIntegral, you're asking for a conversion from Int to some other type. But by restricting the return type of your function to Int, the type you're painstakingly converting those Ints to is... Int! Commented Feb 26, 2014 at 4:32

1 Answer 1

9

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)

Sign up to request clarification or add additional context in comments.

6 Comments

As someone who is new to haskell, why is sum evil?
@devshorts it's based on foldl which can stackoverflow in situations you wouldn't expect. It works with -O2 though search foldl vs foldl'
Excuse my self plugging here, but for Haskell beginners here's a description of why foldl' is better than foldl.
@J.Abrahamson I think you forgot a link? I'd actually love a good tutorial to point to so please share :)
Oh, I did: stackoverflow.com/questions/20356742/… Thanks for notifying me
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.