howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage a b c
| a && b && c >= m = 3
| a && b >= m = 2
| b && c >= m = 2
| a && c >= m = 2
| a || b || c >= m = 1
| otherwise = 0
where m = a + b + c
please why isnt this code running, I'm getting alot of errors i dont understand
You write in your code:
howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage a b c
| a && b >= m = 2
| b && c >= m = 2
| a && c >= m = 2
| a || b || c >= m = 1
| otherwise = 0
where m = a + b + c
I here put one case in boldface, but the error applies to all of them. You write as a condition a && b && c >= m
. For Haskell this means that you write it like a && b && (c >= m)
. Now (&&)
is an operator that takes two booleans as operands, and calculates the logical and of these two. But the operands are no booleans. c >= m
is a boolean, but a
and b
are no booleans.
So we have to write the condition on all operands like:
howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage a b c
| a && b && c >= m = 3
| a && b >= m = 2
| b && c >= m = 2
| a && c >= m = 2
| a || b || c >= m = 1
| otherwise = 0
where m = a + b + c
So now we have booleans, and the program will compile, but it is still semantically incorect. The average is the sum of the elements divided by the number of elements . Here the number of elements is 3, so we should divide it by three. Since dividing a number can lead to numerical errors, and would mean we have to work in the floating point world , it is safer to multiply the element with which we compare with three instead, so:
howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage a b c
| >= m && >= m && >= m = 3
| >= m && >= m = 2
| >= m && >= m = 2
| >= m && >= m = 2
| >= m || >= m || >= m = 1
| otherwise = 0
where m = a + b + c
Now it works, but still it is not elegant: it requires five guards to check the number of conditions, and a total of twelve comparisons. This would thus be rather inefficient.
A better idea is probably to convert True
to 1
and False
to 0
, we can do this with the bool
catamorphism function: bool :: a -> a -> Bool -> a
. If we construct it like bool 0 1
then we have a function that converts False
to 0
, and True
to 1
, we can then write it like:
howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage a b c =
where m = a + b + c
It can further be improved, but I leave this as an exercise.
The &&
operator has type Bool -> Bool -> Bool
. This means that both operands have to be Bool
and the result is also a Bool
.
So for example, in the expression a && b >= m
, the right operand ( b >= m
) is a Bool
, but the left operand ( a
) is not - it's an Int
.
So that's why you get an error: the left operand needs to be a Bool
, too.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.