我正在尝试测试一些使用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.:
我尝试了谷歌搜索并找到了很多规则的代码,但没有应用这些规则的例子。我应该怎样调用上面的后继函数来测试它?
答案 0 :(得分:0)
你混合了两个完全不同的东西:Lambet术语和Racket中的函数。
(λ(x) (+ x 1))
,以便((λ(x) (+ x 1)) 1)
返回2
),< / LI>
在第二个域中,您没有像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)