In Haskell's Way to Logic, Mathematics, and Programming, the authors present two alternative ways of finding the smallest divisor kof nc k > 1, arguing that the second version is much faster than the first. I have problems understanding the reasons (I'm starting).
Here is the first version (p. 10):
ld :: Integer -> Integer -- finds the smallest divisor of n which is > 1
ld n = ldf 2 n
ldf :: Integer -> Integer -> Integer
ldf k n | n `rem` k == 0 = k
| k ^ 2 > n = n
| otherwise = ldf (k + 1) n
If I understand this correctly, the function ldbasically ends up repeating all the integers in the interval [2..sqrt(n)]and stops as soon as one of them divides n, returning it as a result.
The second version, which the authors claim to be much faster, is as follows (p. 23):
ldp :: Integer -> Integer -- finds the smallest divisor of n which is > 1
ldp n = ldpf allPrimes n
ldpf :: [Integer] -> Integer -> Integer
ldpf (p:ps) n | rem n p == 0 = p
| p ^ 2 > n = n
| otherwise = ldpf ps n
allPrimes :: [Integer]
allPrimes = 2 : filter isPrime [3..]
isPrime :: Integer -> Bool
isPrime n | n < 1 = error "Not a positive integer"
| n == 1 = False
| otherwise = ldp n == n
, , 2..sqrt(n) .
: ldpf allPrimes. filter .
, -, 2..sqrt(n) , , ( ), , , n ( ).
, , k n k, . ?