Racket 小打字机。我不知道';我不理解λ的最初第二条戒律的含义;

Racket 小打字机。我不知道';我不理解λ的最初第二条戒律的含义;,racket,lambda-calculus,type-theory,pie-lang,Racket,Lambda Calculus,Type Theory,Pie Lang,我试过下面的例子,但不管y发生与否, 函数f在应用后返回与(λ(y)(fy))相同的值 我想做的是定义一个函数,当Y作为反例出现在Y中时,它与(λ(Y)(fy))不同(->yx),但我不知道如何定义 我是否误解了λ的最初第二条戒律的含义 ;;y does not occurs (claim f (-> Nat Nat)) (define f (λ(y) 0)) ;; both return (the Nat 0) (f 5) ((the (-> Nat Nat)

我试过下面的例子,但不管y发生与否, 函数f在应用后返回与(λ(y)(fy))相同的值

我想做的是定义一个函数,当Y作为反例出现在Y中时,它与(λ(Y)(fy))不同(->yx),但我不知道如何定义

我是否误解了λ的最初第二条戒律的含义

 

;;y does not occurs
(claim f (-> Nat Nat))
(define f
  (λ(y)
    0))

;; both return (the Nat 0)
(f 5)
((the (-> Nat Nat)
   (λ(y)
     (f y)))
  5)


;; y occurs
(claim g  (-> Nat Nat))
(define g
  (λ(y)
    y))

;;both return (the Nat 5)
(g 5)
((the (-> Nat Nat)
   (λ(y)
     (g  y)))
  5)


为了创建一个示例来说明警告的重要性“…只要
y
不出现在
f
”中,我们需要创建一个函数
f
,其中的名称
y
是自由出现的。关于
y
f
中免费的规定至关重要。这也是为什么很难创建这样一个示例的原因:(顶级)函数不能包含自由变量。但是,其他函数内部的函数可以。这是关键

下面是函数
g
,其中包含另一个函数:

(claim g (-> Nat
           (-> Nat
             Nat)))
(define g
  (lambda (y)
    (lambda (x)  ;; Call this inner
      y)))       ;; function "f"
(我选择这样写声明是为了强调我们在考虑函数内部的函数。)

为了确定方向,这个简单的函数
g
需要两个
Nat
参数,并返回第一个参数

让我们调用内部函数
f
。请注意,
f
包含一个自由变量
y
(因此,
f
g
之外没有意义)。让我们用
(lambda(y)(fy))替换
f

(claim g1 (-> Nat
            (-> Nat
              Nat)))
(define g1
  (lambda (y)
    (lambda (y)     ;; Here we've replaced "f"
      ((lambda (x)  ;; with an eta-expanded
         y)         ;; version, introducing
       y))))        ;; the name "y"
我们可以删除应用程序以生成以下表达式:

g1
---------------- SAME AS
(lambda (y)
  (lambda (y)
    ((lambda (x)
       y)
     y)))
---------------- SAME AS
(lambda (y)
  (lambda (y)
    y))
---------------- SAME AS
(lambda (y)
  (lambda (y1)
    y1))
在最后一步中,我将第二个
y
重命名为
y1
,以说明内部函数体中的变量指的是较近的绑定位点,而不是较远的绑定位点

总而言之,我们从一个函数
g
开始,该函数“接受两个(curried)参数并返回第一个”。然后,我们在内部函数周围引入了错误的eta扩展。结果,我们得到了一个函数
g1
,它“接受两个(curried)参数并返回第二个”。显然不等同于原始函数
g

所以这条戒律是关于变量捕获的,这是我们为使用名称而付出的代价。我希望这有帮助

重要提示:

由于饼图检查类型的方式,如果要尝试此示例,则需要在
g
的主体中引入注释:

(claim g1 (-> Nat
            (-> Nat
              Nat)))
(define g1
  (lambda (y)
    (lambda (y)
      ((the (-> Nat Nat)
         (lambda (x)
           y))
       y))))

我不确定我是否理解正确,或者这是否有任何帮助,但请注意,
(λ(y)(fy))
实际上等同于
f
,因为当你应用
((λ(y)(fy))5
,你会得到
(f5)
,这与将
f
应用于5是一样的。