2012-08-07 38 views
3

素數我試圖寫一個返回低於給定數量的所有質數的列表的過程。得到如下X

例如:

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 
+1

'x == True'與'x'相同。 – Vitus 2012-08-07 02:49:50

+0

謝謝維庫斯。我之前沒有這樣做過,但在不編譯的時候添加了它。我想這並沒有什麼區別。 – 2012-08-07 02:58:28

回答

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. xInt類型,(/) :: Fractional a => a -> a -> a不能適用於它。你大概的意思num <= x `div` 22 * num <= x

    divOdd :: Int Int -> Bool 
    divOdd x num | mod x num == 0 == True 
          | num <= x/2 = divOdd x (num + 2) 
          | otherwise = False 
    
  4. x是類型Int,不[Int]的。 (++) :: [a] -> [a] -> [a]將不適用於它。

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

    也許你的意思是

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

最後,這是生成素數的一個相當低效的方式。你有沒有考慮過篩子? Prime numbers - HaskellWiki可能對你有點難度的權利,但會顯示有多少不同的策略。

+0

非常感謝。這些確實是我的問題。正如你可能已經猜到的,我對Haskell相當陌生。我會研究篩,謝謝你的建議。 – 2012-08-07 03:07:00

+0

可能需要反引號逃逸中綴使用'\'DIV \'' – roldugin 2012-08-07 03:14:30

+0

@roldugin堆棧溢出的降價使得很難插入內嵌代碼反引號 - 比在註釋中的問題和答案的工作方式不同 - 但我已經固定它;現在應該是正確的。 – ephemient 2012-08-07 03:35:33

2

這裏是你的函數使用list comprehensions(也in 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 is a function defined in standard Prelude。它會在列表中的條目進行測試,從左至右,看是否都是True。它會停止在遇到的第一個False條目,所以其餘的不會被探索。

有時,當代碼更直觀時,更容易看到如何改進它。

+0

您isPrime將檢查每次3個條件,最好是具有素數的無限名單,並採取從它 – 2012-08-07 09:09:30

+0

X元素@Vixen它不是「地雷」; :)我只是用一種不同的形式寫下了OP代碼,這是IMO更清晰,更容易看到如何改進。 :)你是對的;作爲一個獨立的功能,它必須檢查他們,所以應該由內部到「質數」,因此額外的檢查可以被丟棄,等等,等等,我想提供OP一個簡單的出發點。 – 2012-08-07 09:29:48