3

指定された数値以下のすべての素数のリストを返すプロシージャを作成しようとしています。

例えば:

Prelude>primes 8  
[2,3,5,7]  

取得したファイルを読み込もうとすると、Parse error in pattern Failed, modules loaded: none.誰かが私を正しい方向に向けることができれば、感謝します。

primes :: Int -> [Int]
primes x < 2 = []
primes x | isPrime x == True = primes (x - 1) ++ x
         | otherwise = primes (x - 1)

isPrime :: Int -> Bool
isPrime x | x < 2 = False
          | x == 2 || x == 3 = True
          | divEven x == True = False
          | divOdd x 3 == True = False
          | otherwise = True

divEven :: Int -> Bool
divEven x | mod x 2 == 0 = True
          | otherwise = False

divOdd :: Int Int -> Bool
divOdd x num | mod x num == 0 == True
             | num <= x/2 = divOdd x (num + 2)
             | otherwise = False
4

2 に答える 2

7

小さな間違いの集まり。

  1. 構文が正しくありません。

    primes x < 2 = []
    

    おそらくあなたが意味した

    primes x | x < 2 = []
    

    同様に、あなたが書く場所

    divOdd x num | mod x num == 0 == True
    

    あなたはおそらく意味した

    divOdd x num | mod x num == 0 = True
    
  2. 型シグネチャ

    divOdd :: Int Int -> Bool
    

    有効じゃない。あなたはおそらく意味した

    divOdd :: Int -> Int -> Bool
    
  3. xはタイプIntであり、(/) :: Fractional a => a -> a -> a適用できません。あなたはおそらくnum <= x `div` 2またはを意味し2 * num <= xます。

    divOdd :: Int Int -> Bool
    divOdd x num | mod x num == 0 == True
                 | num <= x/2 = divOdd x (num + 2)
                 | otherwise = False
    
  4. xIntではありません[Int](++) :: [a] -> [a] -> [a]それに適用されません。

    primes x | isPrime x == True = primes (x - 1) ++ x
    

    おそらくあなたが意味した

    primes x | isPrime x == True = primes (x - 1) ++ [x]
    

最後に、これは素数を生成するかなり非効率的な方法です。ふるいについて考えたことはありますか? 素数 - HaskellWikiは今のあなたには少し難しいかもしれませんが、多くの異なる戦略を示しています。

于 2012-08-07T03:00:56.190 に答える
2

これは、リスト内包表記を使用して関数を書き直したものです( Wikipedia にもあります)。おそらく、これはより視覚的に明らかです:

primes :: Int -> [Int]
primes x | x<2  = [] 
         | x<4  = [2..x]
         | True = primes (x-1) ++ [x | isPrime x]

あなたisPrime

isPrime x = x > 1 && 
          ( x < 4 || 
            and [ rem x n /= 0 | n <- 2 : [3,5..(div x 2)+2] ] )

and標準の Prelude で定義されている関数です。リスト内のエントリを左から右にテストして、すべてがTrue. 最初に見つかったエントリで停止するFalseため、残りのエントリは探索されません。

コードがより視覚的に明確になると、コードを改善する方法が簡単にわかる場合があります。

于 2012-08-07T05:27:55.940 に答える