我试图在Haskell中定义自然数乘法,并继续得到下面的错误(对应于下面的第二个natMult定义)。
Prelude> natMult (S (S Z)) (S (S Z))
*** Exception: <interactive>:(4,5)-(5,45): Non-exhaustive patterns in function natPlus
这是我的代码:
data Nat = Z | S Nat deriving (Show)
natPlus :: Nat -> Nat -> Nat
natPlus Z a = a
natPlus (S a) (S b) = natPlus a (S (S b))
经过一些修补,我意识到这个定义工作正常,而下面的第二个则被打破了。唯一的区别是natPlus的输入参数的顺序。
-- works fine
natMult :: Nat -> Nat -> Nat
natMult Z a = Z
natMult (S a) b = natPlus (natMult a b) b
-- gives gives the error above
natMult :: Nat -> Nat -> Nat
natMult Z a = Z
natMult (S a) b = natPlus b (natMult a b)
有人可以解释为什么会出现这个错误吗?
--- ---编辑 以下定义已完成并解决了问题。感谢您的建议
natPlus Z a = a
natPlus (S a) b = natPlus a (S b)
答案 0 :(得分:5)
如果出现Non-exhaustive patterns in function natPlus
错误,使用-Wincomplete-patterns
标记进行编译会很有用。如果我们用这个标志编译程序,我们得到:
$ ghci -Wincomplete-patterns
GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help
Prelude> data Nat = Z | S Nat deriving (Show)
Prelude> :{
Prelude| natPlus :: Nat -> Nat -> Nat
Prelude| natPlus Z a = a
Prelude| natPlus (S a) (S b) = natPlus a (S (S b))
Prelude| :}
<interactive>:4:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘natPlus’: Patterns not matched: (S _) Z
因此,编译器警告我们,对于natPlus
,案例natPlus (S _) Z
不涵盖。由于这是一个练习,我建议你定义这个案例。所以你的代码应该是这样的:
natPlus :: Nat -> Nat -> Nat
natPlus Z a = a
natPlus (S a) (S b) = natPlus a (S (S b))
natPlus (S a) Z = -- ... your code here ...
请注意,您可以通过实现更通用的模式来解决此问题(例如natPlus a Z
,您可以尝试在两个子句中定义它,例如natPlus Z a = -- ...
和natPlus (S a) b = -- ...