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

时间:2015-09-04 02:41:27

标签: racket lambda-calculus

我正在尝试测试一些使用Racket编写的lambda演算函数,但测试用例没有太多运气。例如给定一个定义

; successor function
(define my_succ (λ (one)
                 (λ (two)
                   (λ (three)
                     (two ((one two) three))))))

我正在尝试将其应用于1 2 3,期望2的继任者为3

(((my_succ 1) 2) 3)

逻辑是因为my_succ是一个函数,它接受一个arg并将它传递给另一个函数,该函数接受一个arg将其传递给第三个带有一个arg的函数。但是我得到了

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

我尝试了谷歌搜索并找到了很多规则的代码,但没有应用这些规则的例子。我应该怎样调用上面的后继函数来测试它?

2 个答案:

答案 0 :(得分:0)

你混合了两个完全不同的东西:Lambet术语和Racket中的函数。

  1. 在Racket中你可以有匿名函数,可以用λ表示法编写(比如返回整数后继的(λ(x) (+ x 1)),以便((λ(x) (+ x 1)) 1)返回2),< / LI>
  2. Pure Lambda Calculus中你只有lambda术语,用类似的表示法编写,可以解释为函数。
  3. 在第二个域中,您没有像0, 1, 2, ...这样的自然数字,但是您只有 lambda术语,并且表示数字。例如,如果您使用所谓的Church numerals,则表示(在技术术语编码中)数字0,其中lambda术语为λf.λx.x,{{ 1}} 1λf.λx.f x 2等等。

    因此,函数λf.λx.f (f x)(对于用此编码表示的数字)对应于一个术语,在Racket表示法中,它是您编写的函数,但您不能将其应用于{{1}这样的数字},successor等等,但只对其他lambda表达式,你可以这样写:

    0

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

    #<procedure>

    产生1,因为如果你比较Racket中的两个程序,你总是得到假(例如(equal? (successor zero) (λ(f) (λ(x) (f x)))) 产生#f),除非你比较“相同”(在“意义上”)相同的内存单元格“)值((equal? (λ(x)x) (λ(x)x))给出#f)。这是因为,为了正确比较两个函数,你应该比较无限的几组(输入,输出)!

    另一种可能性是将lambda术语表示为Racket中的某种结构,因此您可以表示Church数字,以及“普通”lambda术语,并定义函数(equal? zero zero)(或更好{{1}执行lambda-reduction。

答案 1 :(得分:-2)

您正在尝试应用柯里化。

(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 中的实现: enter image description here