Итак, я составляю список простых чисел, чтобы помочь мне изучить haskell, используя простое пробное деление (нет ничего сложного, пока я не стану лучше с языком). Я пытаюсь использовать следующий код:
primes = 2 : [ x | x <- [3..], all (\p -> (mod x p) /= 0) primes]
Загружается без ошибок. Тем не менее:
>take 2 primes
[2ERROR - C stack overflow
Я пробовал то же самое с вложенными списками. Не работает Я предполагаю, что я делаю слишком много рекурсивных вызовов, но этого не должно быть, если я вычисляю только одно простое число. На мой взгляд, ленивая оценка должна сделать так, чтобы take 2 primes
делал что-то вроде:
primes = 2 : [ 3 | all (\p -> (mod 3 p) /= 0) [2] ]
Что не требует таких больших вычислений - mod 3 2 == True
, поэтому all (\p -> (mod 3 p) /= 0) == True
, что означает take 2 primes == [2, 3]
, верно? Я не понимаю, почему это не работает. Надеюсь, кто-то, кто намного лучше разбирается в черной магии функционального программирования, может мне помочь ...
Это на объятиях, если это что-то меняет.
РЕДАКТИРОВАТЬ - я смог придумать это решение (не очень):
primes = 2 : [ x | x <- [3..], all (\p -> (mod x p) /= 0) (takeWhile (<= (ceiling (sqrt (fromIntegral x)))) primes)]
EDIT2 - программа отлично работает при интерпретации через HUGS или GHCi, но когда я пытаюсь скомпилировать ее с GHC, выдает test: <<loop>>
. Кто-нибудь знает в чем проблема?