我的理解是Eta转换如下:
作为 eta缩减
venv
所以
(lambda (x) (M x)) -> M
要解决的问题:
作为 eta扩展
(lambda (x) ((lambda (y) (y y)) x)) ->
(lambda (y) (y y))
答案 0 :(得分:1)
带有1个参数的函数的Eta扩展会转换生成该函数的任何表达式,并生成一个将其包装在lambda中的表达式,该lambda仅在调用该函数时才对该表达式进行求值。
可以说表达式E
产生1个参数的函数:
E
它的eta扩展是一个带参数的lambda,并委托给E
(lambda (x) (E x))
使用新变量x
的地方,该变量在E
中不是免费的。这就像将(f x)
定义为(g x)
一样,因此此新功能应与E
等效。
例如,如果E
是诸如y
之类的变量,则eta扩展名可以将y
变成(lambda (x) (y x))
。但是,如果E
包含变量x
,那么您将不得不生成另一个变量而不是x
,因此eta扩展x
可能会产生(lambda (x2) (x x2))
。
E
和eta扩展版本(lambda (x) (E x))
之间的主要区别在于评估E
的时间。仅使用E
,表达式E
就立即被计算一次。但是,使用eta扩展(lambda (x) (E x))
时,E
的求值被延迟到第一次调用该函数的时间,并且每次调用该函数时都重新求E
的求值。在具有副作用的语言中,您可以在E
的一部分中用打印语句来证明这一点。
让E
为:
(begin (displayln "E") f)
然后E
的eta扩展为:
(lambda (x) ((begin (displayln "E") f) x))
如果将g
定义为E
,则在评估该定义时会得到显示。
> (define g (begin (displayln "E") f))
E
调用g
时,它不必再次进行评估,因此不会打印更多E
s
> (g 1)
> (g 2)
但是,如果您将g
定义为eta扩展,那么您将无法获得该显示。
> (define g (lambda (x) ((begin (displayln "E") f) x)))
相反,当您使用参数g
(g 1)
(g 2)
调用(g 3)
时,它将为每个参数打印出E
> (g 1)
E
> (g 2)
E
> (g 3)
E
您的第一个eta归约变换(lambda (x) (M x))
到M
的示例,其中x
在M
中不是空闲的。 Eta扩展是相反的,因此它将M
转换为(lambda (x) (M x))
,在这里必须选择x
中不空闲的M
。
您的第二个eta归约转换示例(lambda (x) ((lambda (y) (y y)) x))
到(lambda (y) (y y))
。同样,eta扩展是相反的,因此,如果给定(lambda (y) (y y))
,它将产生(lambda (x) ((lambda (y) (y y)) x))
。
您的第三个示例是不同的。您正在尝试对(lambda (y) (y y))
进行eta扩展,根据第二个示例,它应该生成(lambda (x) ((lambda (y) (y y)) x))
。但是您的示例说了些不同:
(lambda (y) (y y))
-> (lambda (x y) (y y x))
应该在哪里
(lambda (y) (y y))
-> (lambda (x) ((lambda (y) (y y)) x))