让我们添加一些类型签名:
type Nat a = (a -> a) -> a -> a
zero :: Nat a
zero = (\f z -> z)
one :: Nat a
one = (\f z -> f z)
two :: Nat a
two = (\f z -> f (f z))
iszero :: Nat (a -> a -> a) -> a -> a -> a
iszero = (\n -> n (\x -> (\x y -> y)) (\x y -> x))
mult :: Nat a -> Nat a -> Nat a
mult = (\m n -> (\s z -> m (\x -> n s x) z))
如您所见,除了iszero
.
让我们看看你的表达会发生什么:
*Main> :t (\n -> (iszero n) one n)
<interactive>:1:23:
Occurs check: cannot construct the infinite type:
a0
=
((a0 -> a0) -> a0 -> a0)
-> ((a0 -> a0) -> a0 -> a0) -> (a0 -> a0) -> a0 -> a0
Expected type: Nat a0
Actual type: Nat (Nat a0 -> Nat a0 -> Nat a0)
In the third argument of `iszero', namely `(mult n one)'
In the expression: (iszero n) one (mult n one)
看看错误如何使用我们的Nat
别名!
我们实际上可以使用更简单的表达式得到类似的错误\n -> (iszero n) one n
。这就是问题所在。既然我们在打电话iszero n
,我们就必须有n :: Nat (b -> b -> b)
。此外,由于iszero
s 类型,第二个和第三个参数,n
并且one
,必须具有类型b
。现在我们有两个关于 类型的方程n
:
n :: Nat (b -> b -> b)
n :: b
这是不可调和的。真可惜。