Racket 如何在球拍中应用lambda演算规则?

Racket 如何在球拍中应用lambda演算规则?,racket,lambda-calculus,Racket,Lambda Calculus,我正在尝试测试一些lambda演算函数,这些函数是我用Racket编写的,但在测试用例中运气不好。例如给出了一个定义 ; successor function (define my_succ (λ (one) (λ (two) (λ (three) (two ((one two) three)))))) 我试图将其应用于1233,希望通过这样做,2的继任者将是3 (((my_suc

我正在尝试测试一些lambda演算函数,这些函数是我用Racket编写的,但在测试用例中运气不好。例如给出了一个定义

; successor function
(define my_succ (λ (one)
                 (λ (two)
                   (λ (three)
                     (two ((one two) three))))))
我试图将其应用于1233,希望通过这样做,2的继任者将是3

(((my_succ 1) 2) 3)
逻辑是,因为my_succ是一个函数,它接受一个参数并将其传递给另一个函数,该函数接受一个参数并将其传递给接受一个参数的第三个函数。但我明白了

application: not a procedure;
 expected a procedure that can be applied to arguments
  given: 1
  arguments.:

我试着在谷歌上搜索,找到了很多规则的代码,但没有这些规则的应用实例。我应该如何调用上面的后续函数来测试它?

您混合了两种完全不同的东西:lambda术语和Racket中的函数

  • 在Racket中,您可以使用匿名函数,这些匿名函数可以用λ表示法编写(如
    (λ(x)(+x1))
    返回整数的后继函数,因此
    ((λ(x)(+x1))1
    返回
    2
  • 在这种情况下,只有lambda术语,它们用类似的表示法编写,并且可以解释为函数
  • 在第二个域中,没有像
    0,1,2,…
    这样的自然数,但只有lambda项,并以此表示数字。例如,如果你使用所谓的,你用λf.λx.x表示数字
    0
    1
    表示
    λf.λx.f
    2
    表示
    λf.λx.f(fx)
    等等

    因此,函数
    后继者
    (对于用这种编码表示的数字)对应于一个术语,在Racket表示法中,这个术语就是您编写的函数,但是您不能将它应用于像
    0
    1
    等数字,而只能应用于其他lambda表达式,也就是说,您可以编写如下内容:

    (define zero (λ(f) (λ (x) x)))   ; this correspond to λf.λx.x
    
    (successor zero)
    
    Racket中的结果是一个过程(它将打印为:
    #
    ),但是如果您尝试测试您的结果是否正确,并将其与
    1
    的功能编码进行比较,您会发现一些奇怪的情况。事实上:

    (equal? (successor zero) (λ(f) (λ(x) (f x))))
    
    产生
    #f
    ,因为如果你比较球拍中的两个程序,你总是会得到false(例如
    (等于?(λ(x)x)(λ(x)x))
    产生
    #f
    ),除非你比较“相同”(在“相同存储单元”的意义上)值(
    (等于零)
    给出
    #t
    )。这是因为,为了正确比较两个函数,您应该比较无穷多组耦合(输入、输出)


    另一种可能是将lambda术语表示为Racket中的某种结构,因此您可以表示Church数字以及“正常”lambda术语,并定义一个函数
    apply
    (或者更好的
    reduce
    )执行lambda缩减。

    您混合了两种完全不同的东西:lambda术语和Racket中的函数

  • 在Racket中,您可以使用匿名函数,这些匿名函数可以用λ表示法编写(如
    (λ(x)(+x1))
    返回整数的后继函数,因此
    ((λ(x)(+x1))1
    返回
    2
  • 在这种情况下,只有lambda术语,它们用类似的表示法编写,并且可以解释为函数
  • 在第二个域中,没有像
    0,1,2,…
    这样的自然数,但只有lambda项,并以此表示数字。例如,如果你使用所谓的,你用λf.λx.x表示数字
    0
    1
    表示
    λf.λx.f
    2
    表示
    λf.λx.f(fx)
    等等

    因此,函数
    后继者
    (对于用这种编码表示的数字)对应于一个术语,在Racket表示法中,这个术语就是您编写的函数,但是您不能将它应用于像
    0
    1
    等数字,而只能应用于其他lambda表达式,也就是说,您可以编写如下内容:

    (define zero (λ(f) (λ (x) x)))   ; this correspond to λf.λx.x
    
    (successor zero)
    
    Racket中的结果是一个过程(它将打印为:
    #
    ),但是如果您尝试测试您的结果是否正确,并将其与
    1
    的功能编码进行比较,您会发现一些奇怪的情况。事实上:

    (equal? (successor zero) (λ(f) (λ(x) (f x))))
    
    产生
    #f
    ,因为如果你比较球拍中的两个程序,你总是会得到false(例如
    (等于?(λ(x)x)(λ(x)x))
    产生
    #f
    ),除非你比较“相同”(在“相同存储单元”的意义上)值(
    (等于零)
    给出
    #t
    )。这是因为,为了正确比较两个函数,您应该比较无穷多组耦合(输入、输出)


    另一种可能是将lambda术语表示为Racket中的某种结构,因此您可以表示Church数字以及“正常”lambda术语,并定义一个函数
    apply
    (或者更好的
    reduce
    )来执行lambda reduce。

    您正在尝试应用currying

    (define my_succ
      (lambda(x)(
         lambda(y)(
           lambda(z)(
                  (f x y z)))))
    
    (define (add x y z)
      (+  x y z))
    
    ((( (my_succ add)1)2)3)
    
    DR Racket中的实现:

    您正在尝试使用咖喱

    (define my_succ
      (lambda(x)(
         lambda(y)(
           lambda(z)(
                  (f x y z)))))
    
    (define (add x y z)
      (+  x y z))
    
    ((( (my_succ add)1)2)3)
    
    DR Racket中的实现: