我正在尝试编写一个 Erasthosthenes 函数的筛子,它为用户提供从 2 到他的上限的所有质数。所以我写了这段代码:

main = do
putStrLn "Upper Limit"
g <- readLn
let sieve [] = []
let sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0]
let primes = sieve [2..g]
print primes

代码编译并为我提供了正确的解决方案,但我在解决方案结束时收到此异常:
*** 异常(exception):函数筛中的非穷尽模式
所以我检查了哪些模式不匹配。
warning: [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In an equation for `sieve': Patterns not matched: (_:_)

warning: [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In an equation for `sieve': Patterns not matched: []

我不明白,因为我已经给出了 let sieve [] = []我认为 _ 在 Haskell 中意味着任何变量,那么模式 (:) 是什么意思?
任何帮助,将不胜感激。

最佳答案

问题是您 在两个单独的 sieve 语句 中定义了 let 。因此,Haskell 编译器认为您定义了 两个单独的 sieve 函数 。因此,第一个 sieve 缺少 (_:_) 模式,后者缺少 [] 模式。

如果您稍后使用 sieve ,Haskell 编译器将链接到最近的一个,因此 sieve 中的后者(因此调用 let primes = sieve [2..g] )只会知道第二个 sieve 定义(因此会在列表末尾出错) .

您可以使用以下 let 语句解决此问题:

let { sieve [] = [] ; sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0] }

关于haskell - GHCi 中定义的函数中的非穷尽模式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44096908/

10-12 15:48