Để giúp tôi tìm hiểu Haskell, tôi đang làm việc thông qua các vấn đề trên Project Euler. Sau khi giải quyết từng vấn đề, tôi kiểm tra giải pháp của mình chống lại Haskell wiki trong một nỗ lực để tìm hiểu các phương pháp mã hóa tốt hơn. Dưới đây là the solution-problem 3:Tại sao đoạn mã Haskell này không phải đệ quy vô hạn?
primes = 2 : filter ((==1) . length . primeFactors) [3,5..]
primeFactors n = factor n primes
where
factor n (p:ps)
| p*p > n = [n]
| n `mod` p == 0 = p : factor (n `div` p) (p:ps)
| otherwise = factor n ps
problem_3 = last (primeFactors 317584931803)
đọc ngây thơ của tôi của việc này là primes
được định nghĩa về primeFactors
, được xác định theo primes
. Vì vậy, việc đánh giá primeFactors 9
sẽ thực hiện theo quy trình này:
- Đánh giá
factor 9 primes
. - Yêu cầu
primes
cho phần tử đầu tiên, là 2. - Yêu cầu
primes
cho phần tử tiếp theo của nó. - Là một phần của quá trình này, hãy đánh giá
primeFactors 3
. - Yêu cầu
primes
cho phần tử đầu tiên, là 2. - Yêu cầu
primes
cho phần tử tiếp theo của nó. - Là một phần của quá trình này, hãy đánh giá
primeFactors 3
. - ...
Nói cách khác, các bước 2-4 sẽ lặp lại vô hạn. Rõ ràng là tôi đã nhầm lẫn, khi thuật toán kết thúc. Tôi đang làm gì ở đây?
vì, như câu trả lời ở đây nói, 'nguyên tố' chỉ truy cập' số nguyên tố 'cho đến khi bình phương của một số nguyên vượt quá số đang được kiểm tra, mã đó tương đương với 'số nguyên tố = 2: [n | n <- [3 ..], tất cả ((> 0) .rem n) $ takeWhile ((<= n). (^ 2)) số nguyên tố] 'rõ ràng là không lặp. –