Your main problem seems to be that you still think imperative (with the insert
) - also ()
is the value unit - you probably wanted to write []
(the empty list) instead - but still the xs
here is totally undefined so you would have to fix this too (and I don't see how to be honest).
perfect numbers
I think I can see a basic idea in there, and I think the best way to fix this is to go full list-comprehension (as you seem to understand them quite well) - here is a version that should work:
listX n = [ x | x <- [1..n], sum [ y | y <- [1..x-1], x `mod` y == 0] == x]
As you can see I changed this a bit - first I check all x
from 1
to n
if they could be perfect - and I do this by checking by summing up all proper divisors and checking if the sum is equal to x
(that's the job of the sum [...] == x
part) - in case you don't know this works because you can add guards to list comprehensions (the sum [..] == x
filters out all values of x
where this is true).
a nicer version
to make this a bit more readable (and separate the concerns) I would suggest writing it that way:
properDivisors :: Integer -> [Integer]
properDivisors n = [ d | d <- [1..n-1], n `mod` d == 0]
isPerfect :: Integer -> Bool
isPerfect n = sum (properDivisors n) == n
perfectNumbers :: [Integer]
perfectNumbers = filter isPerfect [1..]
perfectNumbersUpTo :: Integer -> [Integer]
perfectNumbersUpTo n = takeWhile (<= n) perfectNumbers