그래서 나는 소수를 지연 생성하는 방법을 연구하고 있었고,이 모든 세 가지 정의를 생각해 냈습니다.이 세 정의는 모두 같은 방식으로 작동합니다. 각각의 새로운 정수가 이전의 소수 : 그것은 소수의 수 의 순서에 작업이 필요합니다 내가 생각 모든 정수 (대한 f_ = f (const True)
을 재 계산 피할 수 있기 때문에하스켈 스타일/효율성
primes1 :: [Integer]
primes1 = mkPrimes id [2..]
where mkPrimes f (x:xs) =
if f (const True) x
then
let g h y = y `mod` x > 0 && h y in
x : mkPrimes (f . g) xs
else
mkPrimes f xs
primes2 :: [Integer]
primes2 = mkPrimes id (const True) [2..]
where mkPrimes f f_ (x:xs) =
if f_ x
then
let g h y = y `mod` x > 0 && h y in
x : mkPrimes (f . g) (f $ g $ const True) xs
else
mkPrimes f f_ xs
primes3 :: [Integer]
primes3 = mkPrimes [] [2..]
where mkPrimes ps (x:xs) =
if all (\p -> x `mod` p > 0) ps
then
x : mkPrimes (ps ++ [x]) xs
else
mkPrimes ps xs
그래서 나에게 보인다는 primes2
는 primes1
보다 약간 더 빠르게 처리 될 우리 지금까지 찾은 것), enc 할 때만 업데이트합니다. 새 총리를 기른다.
그냥 비 과학적 테스트에서 (ghci에서 take 1000
를 실행)는 primes3
빠르게 실행 primes2
이상처럼 보인다.
나는이에서 교훈을, 그리고 내가 배열에 대한 작업 같은 기능을 나타낼 수 있다면, 내가 효율성 후자의 방식을 구현해야한다고 가정, 또는 뭔가 다른 여기에 무슨이해야 ?
'primes3'에서'all'을 호출하는 것은 엄청난 과잉입니다 -'sqrt'의'x'를 초과하지 않는 소수만을 취하면 충분합니다 - 따라서 동일한 소수 목록을 사용할 수 있습니다 (primitive4 = 2 : filter (\ x-> all (() = 0). (rem x)) $ takeWhile ((<= x). (^ 2)) primes4) [3,5 ..]','O (n^1.45)'에 대해 경험적으로,'n' 소수에서 생성됨 - 질문에있는 세 가지 버전 모두가 2 차적으로 보임 - 함수를 어떻게 만들지 'sqrt x' 아래에있는 것 이외에 * all * 소수점으로 테스트하십시오. –