感谢所有回答我问题的人。我研究了你的回答。为了确保我理解我所学到的东西,我已经写了我自己对我的问题的答案。如果我的回答不正确,请告诉我。
我们从 和 的类型k
开始s
:
k :: t1 -> t2 -> t1
k = (\a x -> a)
s :: (t3 -> t4 -> t5) -> (t3 -> t4) -> t3 -> t5
s = (\f g x -> f x (g x))
让我们首先确定(s k)
.
召回s
的定义:
s = (\f g x -> f x (g x))
代替k
签约f
结果(\f g x -> f x (g x))
:
(\g x -> k x (g x))
重要g 和 x 的类型必须与k
' 的类型签名一致。
回想一下k
具有这种类型签名的:
k :: t1 -> t2 -> t1
所以,对于这个函数定义,k x (g x)
我们可以推断:
的类型x
是 的k
第一个参数的类型,即 type t1
。
k
的第二个参数的类型是t2
,所以 的结果(g x)
必须是t2
。
g
hasx
作为我们已经确定的参数,它具有 type t1
。所以类型签名(g x)
是(t1 -> t2)
.
的结果的类型k
是t1
,所以的结果(s k)
是t1
。
所以,类型签名(\g x -> k x (g x))
是这样的:
(t1 -> t2) -> t1 -> t1
接下来,k
被定义为始终返回其第一个参数。所以这:
k x (g x)
与此签订合同:
x
还有这个:
(\g x -> k x (g x))
与此签订合同:
(\g x -> x)
好的,现在我们已经弄清楚了(s k)
:
s k :: (t1 -> t2) -> t1 -> t1
s k = (\g x -> x)
现在让我们确定s (s k)
.
我们以同样的方式进行。
召回s
的定义:
s = (\f g x -> f x (g x))
代替(s k)
签约f
结果(\f g x -> f x (g x))
:
(\g x -> (s k) x (g x))
重要g
和的类型x
必须与(s k)
的类型签名一致。
回想一下(s k)
具有这种类型签名的:
s k :: (t1 -> t2) -> t1 -> t1
所以,对于这个函数定义,(s k) x (g x)
我们可以推断:
的类型x
是 的(s k)
第一个参数的类型,即 type (t1 -> t2)
。
(s k)
的第二个参数的类型是t1
,所以 的结果(g x)
必须是t1
。
g
hasx
作为它的参数,我们已经确定它有 type (t1 -> t2)
。所以类型签名(g x)
是((t1 -> t2) -> t1)
.
的结果的类型(s k)
是t1
,所以的结果s (s k)
是t1
。
所以,类型签名(\g x -> (s k) x (g x))
是这样的:
((t1 -> t2) -> t1) -> (t1 -> t2) -> t1
之前我们确定s k
有这个定义:
(\g x -> x)
也就是说,它是一个接受两个参数并返回第二个参数的函数。
因此,这:
(s k) x (g x)
与此签订的合同:
(g x)
还有这个:
(\g x -> (s k) x (g x))
与此签订合同:
(\g x -> g x)
好的,现在我们已经弄清楚了s (s k)
。
s (s k) :: ((t1 -> t2) -> t1) -> (t1 -> t2) -> t1
s (s k) = (\g x -> g x)
最后,将 的类型签名s (s k)
与此函数的类型签名进行比较:
p = (\g x -> g x)
的类型p
是:
p :: (t1 -> t) -> t1 -> t
p
并且s (s k)
具有相同的定义(\g x -> g x)
,那么为什么它们具有不同的类型签名?
s (s k)
具有不同类型签名的原因p
是对p
. 我们看到s
in(s k)
被约束为与 的类型签名一致k
,而 first s
ins (s k)
被约束为与 的类型签名一致(s k)
。因此, 的类型签名s (s k)
由于其参数而受到限制。尽管p
和s (s k)
具有相同的定义,但约束g
和x
不同。