使用 otherwise 时如何获得 non-exhaustive patterns 异常
How is it possible to get `Non-exhaustive patterns` exception when using `otherwise`
我试图证明 p_1 * ... * p_k + 1
形式的数字不都是质数,为此,我编写了这段代码
sieve :: [Integer] -> [Integer]
sieve (0:xs) = sieve xs
sieve (x:xs) = x : sieve (mark x xs)
where
mark :: Integer -> [Integer] -> [Integer]
mark n (y:ys)
| rem y n == 0 = 0 : (mark n ys)
| otherwise = y : (mark n ys)
checkPrime' :: Integer -> Bool
checkPrime' n = elem n (sieve [n])
listPrimeFromTo' :: Integer -> Integer -> [Integer]
listPrimeFromTo' k n = sieve [k..n]
checkEulerPrimes = forall [(product xs) + 1| n <- [2..], let xs = listPrimeFromTo' 2 n] checkPrime'
我得到这个异常:
*** Exception: Ch3.hs:(11,2)-(13,31): Non-exhaustive patterns in function mark
但是,在函数mark
的定义中,我用的是otherwise
,怎么可能出现函数定义没有规定任何规则的情况。我的意思是我认为使用关键字 otherwise
可以确保没有未用尽的模式。
otherwise
确实是一个永远成功的守卫;但是只有当关联的模式已经匹配时才会考虑守卫。所以,在
foo (x:xs) | otherwise = bar
当 foo
的参数匹配模式 x:xs
时,我们只会看到 bar
作为结果。 otherwise
的类似模式是 _
,它始终匹配并且不绑定任何新变量,因此:
foo (x:xs) | otherwise = bar
foo _ = baz
永远不会抛出不匹配的模式异常。
我试图证明 p_1 * ... * p_k + 1
形式的数字不都是质数,为此,我编写了这段代码
sieve :: [Integer] -> [Integer]
sieve (0:xs) = sieve xs
sieve (x:xs) = x : sieve (mark x xs)
where
mark :: Integer -> [Integer] -> [Integer]
mark n (y:ys)
| rem y n == 0 = 0 : (mark n ys)
| otherwise = y : (mark n ys)
checkPrime' :: Integer -> Bool
checkPrime' n = elem n (sieve [n])
listPrimeFromTo' :: Integer -> Integer -> [Integer]
listPrimeFromTo' k n = sieve [k..n]
checkEulerPrimes = forall [(product xs) + 1| n <- [2..], let xs = listPrimeFromTo' 2 n] checkPrime'
我得到这个异常:
*** Exception: Ch3.hs:(11,2)-(13,31): Non-exhaustive patterns in function mark
但是,在函数mark
的定义中,我用的是otherwise
,怎么可能出现函数定义没有规定任何规则的情况。我的意思是我认为使用关键字 otherwise
可以确保没有未用尽的模式。
otherwise
确实是一个永远成功的守卫;但是只有当关联的模式已经匹配时才会考虑守卫。所以,在
foo (x:xs) | otherwise = bar
当 foo
的参数匹配模式 x:xs
时,我们只会看到 bar
作为结果。 otherwise
的类似模式是 _
,它始终匹配并且不绑定任何新变量,因此:
foo (x:xs) | otherwise = bar
foo _ = baz
永远不会抛出不匹配的模式异常。