this is my code, but it gives me an infinitive loop. i can’t find my mistake, can you help me and give me some advices to find it?
isPrime :: Int -> Bool isPrime n = n > 1 && helper 2 where helper d | d >= n = True | mod n d == 0 = False | otherwise = helper (d + 1) sumPrimeDivs :: Int -> Int sumPrimeDivs n = helper n 2 0 where helper num d result |isPrime d && mod num d == 0 = helper num (d + 1) result + d |d == num = result |otherwise = helper num (d + 1) result
I have to find the sum of all prime divisors of a given number.
The issue is in the last helper function. Sometimes we call
helper p p result where the two first arguments are the same prime
p. This falls in the first case of the definition
|isPrime d && mod num d == 0 = helper num (d + 1) result + d
This makes a recursive call to the helper with
helper p (p+1) result but not the second argument is too large to trigger the termination condition
|d == num = result
Change that to
d >= num instead.
Further in the helper you never change the first and third arguments, so you can omit them. For instance:
sumPrimeDivs :: Int -> Int sumPrimeDivs n = helper 2 where helper d | isPrime d && mod n d == 0 = helper (d + 1) + d | d >= n = 0 | otherwise = helper (d + 1)
(Personally, I’d write the code differently, reordering the cases, making use of list comprehensions, or even using a more efficient algorithm, but I wanted to preserve your original code as much as possible here.)
Alternatively, you might have wanted to use
result as an accumulator, but in that case you need to call
helper (d+1) (result+d) when you recurse.