所以我使用以下数据类型进行此练习
data Nat = Zero | Succ Nat deriving (Eq,Ord,Show,Read)
Run Code Online (Sandbox Code Playgroud)
这可以用于表示自然数,例如2 = Succ(Succ Zero).我实现了一个检查数字是否均匀的函数.
even :: Nat -> Bool
even x = count x `mod` 2 == 0
count :: Nat -> Int
count Zero = 0
count (Succ x) = 1 + count x
Run Code Online (Sandbox Code Playgroud)
它适用于零,但每当我尝试不同的东西,如计数Succ Zero或计数Succ(Succ Zero)
*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
Run Code Online (Sandbox Code Playgroud)
问题不在于函数本身,而是调用函数:
even Succ Zero
Run Code Online (Sandbox Code Playgroud)
或者更详细:
(even Succ) Zero
Run Code Online (Sandbox Code Playgroud)
所以你这里even用Succas参数调用,Succ是一个类型的函数Nat -> Nat,而不是一个Nat本身.为了传递Succ Zero到偶数,你需要使用括号,如:
even (Succ Zero)
Run Code Online (Sandbox Code Playgroud)
话虽这么说,一个人不是需要先皮亚诺数转换为Int以检查它是否甚至与否.人们可以归纳地定义这样的功能:
Zero 甚至;(Succ Zero)是不是均匀; 和(Succ (Succ x))是偶数,当且仅当x是偶数.所以我们可以这样实现:
even' :: Nat -> Bool
even' Zero = True
even' (Succ Zero) = False
even' (Succ (Succ x)) = even' x
Run Code Online (Sandbox Code Playgroud)
或者我们可以引入一个"帮助器"函数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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
247 次 |
| 最近记录: |