divisors
関数を見てみましょう。それは、次の 2 つの問題だけで、ある程度は正しいです。
xs
主張はどうあるべきか?定義から、以下のすべての素数であるように見えますx
- これらを素数候補と呼びましょう。x
だった場合10
、素数候補は になるはずです[2,3,5,7]
。ただし、これは関数が引数として取得するものではありません。あなたのコードでxs
は、素数の無限リストです。
技術的には、divisors
はすべての除数を返すわけではありません。たとえば、divisors 16 [2,3,5,7,11,13]
は返されません。8
しかし、これは些細な問題です。
divisors
したがって、素数の正しいリストで呼び出すことができれば、問題はなく、isPrime
関数も問題ありません。
問題は素数候補のリストを取得することです。わかりやすくするために、最初にコードを示し、次に説明します。
primeLst = 2 : [ x | x <- [3..], isPrime x (takeWhile (\p -> p*p <= x) primeLst)]
2 つの変更を加えました。
primeLst
が含まれていることを確認して2
、前面に貼り付けました。
素数の無限リストから数を取得して、素数をテストしている数の平方根よりも大きい数に達するまで、素数の候補を制限しました。これを行う際に、素数候補の定義をわずかに変更したため、たとえば、 の候補26
は[2,3,5]
ではなく[2,3,5,7,11,13,17,19,23]
. しかし、それでも機能します。
考えるべき 2 つの質問:
素数候補の新しい定義でも機能するのはなぜですか?
次のコード行は、素数候補の元の定義を提供する必要があるように見えますが、なぜ機能しないのでしょうか?
:
primeLst = 2 : [ x | x <- [3..], isPrime x (takeWhile (\p -> p < x) primeLst)]
最後の質問は難しいので、質問があればコメントに投稿してください。