Haskell代码运行报错:无法匹配预期类型Bool与实际类型Int
Great question—let's walk through exactly why your code is failing and how to fix it.
First: The Type Mismatch Error
The big error you mentioned—"Couldn't match expected type ‘Bool’ with actual type ‘Int’"—stems from how you're using logical operators && and ||. In Haskell, these operators only work with boolean values (True/False), but you're passing integers directly to them.
For example, when you write a && b >= m, Haskell evaluates this step-by-step:
- First, it computes
b >= m(which gives a validBoolresult) - Then it tries to combine
a(anInt) with thatBoolusing&&—which is impossible, since&&requires both operands to be booleans.
You need to explicitly compare each number to m before using the logical operator. So instead of a && b >= m, you want a >= m && b >= m.
Second: Your "Average" Isn't Actually an Average
Right now, you've defined m = a + b + c—that's the sum of the three numbers, not their average! Unless your inputs are all zero, this m will be way larger than any individual number, so none of your >= m checks will ever be true. To get the integer average (since we're working with Int), use integer division: m = (a + b + c) div 3.
Third: Condition Logic & Order Issues
Even if you fixed the type errors, your condition structure would cause problems. For example, your first condition a && b && c >= m doesn't check if all three numbers are above the average—it's just invalid syntax. Plus, some of your two-number conditions would never fire if the three-number condition wasn't correctly prioritized first.
Fixed Code
Here's the corrected version that addresses all these issues:
howManyAboveAverage :: Int -> Int -> Int -> Int howManyAboveAverage a b c | a >= m && b >= m && c >= m = 3 | a >= m && b >= m = 2 | b >= m && c >= m = 2 | a >= m && c >= m = 2 | a >= m || b >= m || c >= m = 1 | otherwise = 0 where m = (a + b + c) `div` 3
This version works as intended:
- Returns 3 if all three numbers are at or above the average
- Returns 2 if exactly two are at or above
- Returns 1 if exactly one is at or above
- Returns 0 if none meet the threshold
内容的提问来源于stack exchange,提问作者thecodesalim

