Lambda:Eta转换,扩展,缩减说明

时间:2019-05-05 21:56:52

标签: lambda scheme racket

我的理解是Eta转换如下:

作为 eta缩减

venv
  • 当M不包含x时;

所以

(lambda (x) (M x)) -> M

要解决的问题:

作为 eta扩展

(lambda (x) ((lambda (y) (y y)) x)) -> 
                       (lambda (y) (y y))

1 个答案:

答案 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的示例,其中xM中不是空闲的。 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))