如何在Haskell中交换定义自然数的乘法?

时间:2018-04-16 20:36:55

标签: haskell ghc

我试图在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)

1 个答案:

答案 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 = -- ...