所以我在练习中使用以下数据类型
data Nat = Zero | Succ Nat deriving (Eq,Ord,Show,Read)
这可以用来表示自然数,例如2 = Succ(Succ零)。 我实现了一个检查数字是否为偶数的功能。
even :: Nat -> Bool
even x = count x `mod` 2 == 0
count :: Nat -> Int
count Zero = 0
count (Succ x) = 1 + count x
它对零有效,但是每当我尝试不同的操作时,例如将Succ计数为零或将Succ(计数为零)计数
*Main> even Succ Zero
<interactive>:6:1: error:
* Couldn't match expected type `Nat -> t' with actual type `Bool'
* The function `evenN' is applied to two arguments,
but its type `Nat -> Bool' has only one
In the expression: evenN Succ Zero
In an equation for `it': it = evenN Succ Zero
* Relevant bindings include it :: t (bound at <interactive>:6:1)
<interactive>:6:7: error:
* Couldn't match expected type `Nat' with actual type `Nat -> Nat'
* Probable cause: `Succ' is applied to too few arguments
In the first argument of `evenN', namely `Succ'
In the expression: evenN Succ Zero
In an equation for `it': it = evenN Succ Zero
答案 0 :(得分:7)
问题是不是函数本身,但是您可以像这样调用函数:
even Succ Zero
或更详细:
(even Succ) Zero
因此,您在此处以even
作为参数调用Succ
,Succ
是类型Nat -> Nat
的函数,而不是Nat
本身。为了将Succ Zero
传递给偶数,您需要使用方括号,例如:
even (Succ Zero)
话虽这么说,不是不需要先将Peano数转换为Int
,以检查其是否为偶数。可以归纳定义这样的功能:
Zero
是偶数; (Succ Zero)
甚至不是 ;和(Succ (Succ x))
是偶数,当且仅当x
是偶数。所以我们可以这样实现:
even' :: Nat -> Bool
even' Zero = True
even' (Succ Zero) = False
even' (Succ (Succ x)) = even' x
或者我们可以引入一个“ helper”函数odd' :: Nat -> Bool
,并使用相互递归:
even' :: Nat -> Bool
even' Zero = True
even' (Succ x) = odd' x
odd' :: Nat -> Bool
odd' Zero = False
odd' (Succ x) = even' x