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是 type Int(/) :: 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]
    

最后,这是一种相当低效的生成素数的方法。你考虑过筛子吗? 素数 - 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 回答