Lambda 从方案代码中理解结果
我最近一直在玩弄scheme,并提供了以下代码示例Lambda 从方案代码中理解结果,lambda,functional-programming,scheme,closures,Lambda,Functional Programming,Scheme,Closures,我最近一直在玩弄scheme,并提供了以下代码示例 (define f (lambda (g) (lambda (x) (g (+ (g x) (g x)))))) (define e (lambda (x) (* x 3))) (define d (f e)) (d 4) 输出是 => 72 如果有人能给我一个解释程序如何一步一步地处理这些代码并产生结果的概要,这将有助于我理解这种语言 我的理解非常基本,让我感到不舒服的是(d4),因为我(最初)认为(definedd(fee
(define f (lambda (g) (lambda (x) (g (+ (g x) (g x))))))
(define e (lambda (x) (* x 3)))
(define d (f e))
(d 4)
输出是
=> 72
如果有人能给我一个解释程序如何一步一步地处理这些代码并产生结果的概要,这将有助于我理解这种语言
我的理解非常基本,让我感到不舒服的是(d4)
,因为我(最初)认为(definedd(fee))
需要两个参数。我一直在阅读来自在线链接的材料,但似乎找不到我想要的正确解释。为了
(d 4)
要工作,d
必须是一个过程。因为d
是使用
(define d (f e))
然后
必须返回一个程序。定义了f
的方式,其返回值实际上是一个lambda
表达式
的返回值
(f e)
是
如果替换e
代表的内容,您将得到:
(lambda (x) (* (+ (* x 3) (* x 3)) 3))
因此,
可以翻译成
(define d (lambda (x) (* (+ (* x 3) (* x 3)) 3)))
(* (+ (* 4 3) (* 4 3)) 3)
现在,
可以翻译成
(define d (lambda (x) (* (+ (* x 3) (* x 3)) 3)))
(* (+ (* 4 3) (* 4 3)) 3)
其计算结果为
72
我将用。其思想是,可以用变量的定义替换变量,用过程体中的表达式替换过程应用程序,并将形式参数扩展为它的表达式。例如:
(定义正方形(λ(x)(*x)))
(方框5)
因此我们从(sqrt 5)
开始,因为它启动了进程(不是定义)
(正方形5);=>subst广场
((λ(x)(*x))5);=>应用x=5
(* 5 5) ; ==> 25
现在,让我们对您的示例执行相同的操作:
(定义f(lambda(g)(lambda(x)(g(+(gx)(gxщщ)))
(定义e(λ(x)(*x3)))
(定义d(f e))
(d 4)
或者我们可以从d
开始,因为它的定义是一个表达式(f e)
:
(f e);subs f==>
((lambda(g)(lambda(x)(g(+(gx)(gx‘)’)))e);应用g=e==>
(λ(x)(e(+(ex)(ex)));subst first e==>
(λ(x)((λ(x)(*x3))(+(ex)(ex)));应用x=(+(ex)(ex))=>
(λ(x)(*(+(ex)(ex))3));subst e+应用x=x==>
(λ(x)(*(+(*x3)(*x3))3));现在这是d
因此,实际上f
和e
现在是不相关的,因为通过替换规则,您可以编写(定义d(lambda(x)(*(+(*x3)(*x3))3))
。
然后我们使用它的新定义执行(d4)
:
(d4);subst d==>
((λ(x)(*(+(*x3)(*x3))3))4;应用x=4=>
(* (+ (* 4 3) (* 4 3)) 3) ; ==> 72
我已经手动完成了这项工作,但您可以通过选择“中级学生”为中的简单方案代码自动完成这项工作在左下角的下拉菜单中选择“作为语言”,然后按步骤>|。您的代码有13个步骤。但是,手动执行几次有助于掌握诀窍,您在观看之后会更好地理解,如果您完成了,您会非常好。书籍和视频是免费的,因此您只需支付您的“时间到ace”计划。程序相当于
(let ((f (lambda (g) (lambda (x) (g (+ (g x) (g x)))))))
(let ((e (lambda (x) (* x 3))))
(let ((d (f e)))
(d 4))))
一般来说,应该使用letrec
,而不是let
,但在这里没有区别。letrec
允许过程在其主体内引用自己的名称,即递归。let
不允许此类引用。例如,定义f
的lambda表达式不包含y对f
的引用
现在,通过尝试找出d
的值,将其用作一个函数,以4
的值作为参数调用。因此执行应用程序(f e)
。通常,应用程序((lambda(x)…)v
减少为(let((x v))
:
那是
......
(let ((x 4))
(let ((temp2 (g x)) ; <---
(temp3 (g x)))
(let ((temp1 (+ temp2 temp3)))
(g temp1) )))))))
......
(let ((x 4))
(let ((temp2 ( (lambda (x1) (* x1 3)) x )) ; <---
(temp3 (g x)))
(let ((temp1 (+ temp2 temp3)))
(g temp1) )))))))
......
(let ((x 4))
(let ((temp2 (let (x1 x) (* x1 3))) ; <---
(temp3 (g x)))
(let ((temp1 (+ temp2 temp3)))
(g temp1) )))))))
......
(let ((x 4))
(let ((temp2 (let (x1 4) (* x1 3))) ; <---
(temp3 (g x)))
(let ((temp1 (+ temp2 temp3)))
(g temp1) )))))))
......
(let ((x 4))
(let ((temp2 (* 4 3)) ; <---
(temp3 (g x)))
(let ((temp1 (+ temp2 temp3)))
(g temp1) )))))))
。。。。。。
(让((x 4))
(let((temp2(gx));在部分(lambda(x)(*(+(*x3)(*x3))3))
,为什么操作符只将In替换为e
,而x3
替换为x
?@算法既然e
定义为(lambda(*x3))
,我们就可以将(ex)
替换为(*x3)
。希望这能回答你的问题。啊,我想我已经到了。我还在试着熟悉语法。(ex)
是对e
的过程调用,其中参数是x
?(define d(f e))
定义d
来保存计算(f e)的结果值
,它调用由f
引用的函数,并以e
的值作为参数。最好的解释,谢谢!我刚刚阅读了一些关于lambda演算的文档,现在这对我来说非常有意义。我开始相信函数语言的威力。@sylvestersqr
,而不是sqrt
@ChrisJester Young OMG你说得对。我想要一个比视频中更简单的例子(平方和),我认为square
是个不错的例子,并称之为sqrt
。更新!谢谢:-)
(let ((f (lambda (g) (lambda (x) (g (+ (g x) (g x)))))))
(let ((e (lambda (x) (* x 3))))
(let ((d (f e)))
(d 4))))
(let ((f (lambda (g) (lambda (x) (g (+ (g x) (g x)))))))
(let ((e (lambda (x) (* x 3))))
(let ((d (let ((g e)) ; <---
(lambda (x) (g (+ (g x) (g x)))) )
))
(d 4))))
(let ((f (lambda (g) (lambda (x) (g (+ (g x) (g x)))))))
(let ((e (lambda (x) (* x 3))))
(let ((g e))
(let ((d (lambda (x) (g (+ (g x) (g x))))))
(d 4))))) ; <---
(let ((f (lambda (g) (lambda (x) (g (+ (g x) (g x)))))))
(let ((e (lambda (x) (* x 3))))
(let ((g e))
(let ((d (lambda (x) (g (+ (g x) (g x))))))
(let ((x 4))
(g (+ (g x) (g x))) ))))) ; <---
(let ((f (lambda (g) (lambda (x) (g (+ (g x) (g x)))))))
(let ((e (lambda (x) (* x 3))))
(let ((g e))
(let ((d (lambda (x) (g (+ (g x) (g x))))))
(let ((x 4))
(let ((temp1 (+ (g x) (g x)))) ; <---
(g temp1) ))))))
......
(let ((x 4))
(let ((temp2 (g x)) ; <---
(temp3 (g x)))
(let ((temp1 (+ temp2 temp3)))
(g temp1) )))))))
......
(let ((x 4))
(let ((temp2 ( (lambda (x1) (* x1 3)) x )) ; <---
(temp3 (g x)))
(let ((temp1 (+ temp2 temp3)))
(g temp1) )))))))
......
(let ((x 4))
(let ((temp2 (let (x1 x) (* x1 3))) ; <---
(temp3 (g x)))
(let ((temp1 (+ temp2 temp3)))
(g temp1) )))))))
......
(let ((x 4))
(let ((temp2 (let (x1 4) (* x1 3))) ; <---
(temp3 (g x)))
(let ((temp1 (+ temp2 temp3)))
(g temp1) )))))))
......
(let ((x 4))
(let ((temp2 (* 4 3)) ; <---
(temp3 (g x)))
(let ((temp1 (+ temp2 temp3)))
(g temp1) )))))))
......
(let ((x 4))
(let ((temp2 12)
(temp3 12))
(let ((temp1 24))
(g temp1) ))))))) ; <---
......
(let ((temp1 24))
( (lambda (x2) (* x2 3)) temp1) ))))) ; <---
......
(let (x2 24) (* x2 3)) )))) ; <---
......
(* 24 3) )))) ; <---
......
72 )))) ; []