2014-02-26 3 views
0

주어진 마크 목록에서 평균 마크를 계산하는 함수를 원합니다. 내가 뭘하려고 오전하스켈 Int Int 나누기

getAverageRate :: [Int]->Int 
getAverageRate marks = (fromIntegral (foldr (+) 0 marks))/(fromIntegral (length marks)) 

다음 '길이 표시'에 의해 분할 'foldr'를 사용하여 목록에있는 모든 마크의 합계를 얻을 것입니다 : 이것은 내가 지금까지 만든 것입니다. 이미 'fromIntegral'을 사용하고 있지만이 오류가 계속 나타나고 문제를 찾을 수 없습니다.

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)) 
+0

'fromIntegral'을 호출하면'Int '에서 다른 유형으로의 변환을 요청할 것입니다. 그러나 함수의 리턴 타입을'Int'로 제한함으로써, 당신은 근본적으로 그 Int's를'Int'! –

답변

6

것은 Int는 정수를 나타낸다는 것을, 그래서 의미가 대부분의 부서는 정수하지 않은 일이 발생할 이후 분할 할 수 있도록하지 않습니다.

행복 하 게 우리는 정수 부문 인 div을 가지고, 그래서 당신은 정수 나누기를 사용하지 않을 경우 당신은

average :: [Int] -> Double 
average xs = fromIntegral (sum xs)/fromIntegral (length xs) 

처럼 우리가 할 수있는 뭔가를

average :: [Int] -> Int 
average [] = error "Can't average an empty list" 
average xs = sum xs `div` length xs 

을 할 수있는 모든 것을 격려하기 위해 Double으로 승격합니다.

는 마지막으로 반올림하는 방법을 선택하고 sum 악한 긴 목록을 사용할 때 너무 -O2 컴파일해야 foldl 대신 foldl'의 사용

average xs = round $ fromIntegral (sum xs)/fromIntegral (length xs) 

(친절한 이웃 경고 있음을 자녀로 갈 수있다)

+1

haskell을 처음 접하는 사람으로서, 왜'sum'은 악마입니까? – devshorts

+3

@devshorts 그것은'foldl'에 기반합니다. 여러분이 예상하지 못한 상황에서 stackoverflow를 할 수 있습니다. 그것은 '-O2'와 함께 작동하지만 foldl과 foldl은 일치합니다. – jozefg

+0

자기 혼성의 실례지만 하스켈의 초보자를위한 이유는'foldl'이'foldl'보다 나은 이유에 대한 설명입니다. –