Haskell完美数检测:编写完美数判断函数遇到问题求助
Hey there! Let's get that perfect number function working for you—since you're new to Haskell, I'll walk through this clearly with explanations every step of the way.
First, let's recap what a perfect number is: a positive integer that's equal to the sum of its proper positive divisors (all divisors except the number itself). Classic examples are 6 (1+2+3=6) and 28 (1+2+4+7+14=28).
Step 1: Write a helper function to get proper divisors
First, we need a function that grabs all the proper divisors of a number. Here's a straightforward implementation using Haskell's list comprehensions, which are perfect for this kind of filtering:
properDivisors :: Integral a => a -> [a] properDivisors n = [d | d <- [1..n `div` 2], n `mod` d == 0]
Integral aensures this works for any integer type (Int, Integer, etc.)- We only check up to
ndiv2because any number larger than half of n can't divide n evenly (except n itself, which we intentionally exclude) - The condition
nmodd == 0filters out any numbers that don't divide n cleanly
Step 2: Build the perfect number check function
Now we can use our helper function to create the main check. We'll add a boundary condition first, since perfect numbers are always greater than 1:
isPerfect :: Integral a => a -> Bool isPerfect n | n <= 1 = False -- Numbers ≤1 can't be perfect | otherwise = sum (properDivisors n) == n
- The guard clauses (
| ...) make the logic easy to read: first handle invalid cases, then check if the sum of proper divisors equals the original number
Test it out!
Let's verify with some examples to make sure it works as expected:
main :: IO () main = do print $ isPerfect 6 -- Should print True print $ isPerfect 28 -- Should print True print $ isPerfect 12 -- Should print False print $ isPerfect 496 -- Another perfect number, should print True
Common pitfalls to avoid (in case your original code had issues)
- Forgetting boundary cases: If you didn't handle
n <=1, you might get wrong results (like 1 being incorrectly labeled perfect) - Including the number itself in divisors: Make sure your divisor list doesn't include n—our helper function avoids this by stopping at
n/2 - Using the wrong division operator: In Haskell,
divis for integer division (vs/which is for floats), so we usendiv2instead ofn/2to keep everything integer-based
If you had a specific version of code that wasn't working, feel free to share it and we can debug exactly where it went wrong—but this implementation should get you up and running smoothly!
内容的提问来源于stack exchange,提问作者Mike Noel Higgs

