【问题标题】:Lambda: Eta Conversion, Expansion, Reduction clarificationLambda:Eta 转换、扩展、缩减说明
【发布时间】:2019-05-05 21:56:51
【问题描述】:

我的理解Eta-conversion如下:

作为eta-reduction

(lambda (x) (M x)) -> M
  • 当 M 不包含 x 时;

所以,

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

问题解答:

作为 eta 扩展

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

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

【问题讨论】:

  • 到底是什么问题?您是在问问题中给出的 eta-reductions 和 eta-expansions 是否正确?
  • 另一件事,你所说的语言中的所有函数都是隐式柯里化的吗?换句话说,当您写(lambda (x y) ....) 时,您打算与(lambda (x) (lambda (y) ....)) 相同还是不同?
  • 我在问扩展和缩减是否正确。我认为扩展可能不正确。我首先考虑的是 Lambda Calculus 本身,然后是 Scheme 和 Lisp 作为编程语言实现。谢谢!
  • 我修正了一个看似简单的错字。你的最后一个 sn-p 周围有一对额外的括号,你的意思是 (lambda (z) (y z)) -> y 可能吗?如果是,那么
  • 谢谢。我对 Eta 扩展感到困惑。我想我的还原部分没问题。

标签: lambda scheme racket


【解决方案1】:

具有 1 个参数的函数的 Eta 扩展转换任何生成此类函数的表达式,并生成一个将其包装在 lambda 中的表达式,该表达式仅在调用该函数时才评估该表达式。

假设表达式 E 产生一个 1-argument 函数:

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-expansion (lambda (x) (E x))E 的评估会延迟到函数第一次调用的时间,并且每次调用函数时都会重新评估 E。在具有副作用的语言中,您可以使用作为E 一部分的打印语句来证明这一点。

E 为:

(begin (displayln "E") f)

那么E的eta-expansion是:

(lambda (x) ((begin (displayln "E") f) x))

如果您将g 定义为E,则在评估该定义时会得到显示。

> (define g (begin (displayln "E") f))
E

并且当你调用g时,它不必再次评估它,所以它不会打印更多Es

> (g 1)
> (g 2)

但是,如果您将 g 定义为 eta 扩展,那么您将无法获得该显示。

> (define g (lambda (x) ((begin (displayln "E") f) x)))

相反,当您使用参数(g 1) (g 2) (g 3) 调用g 时,它会为每个参数打印一个E

> (g 1)
E
> (g 2)
E
> (g 3)
E

这如何适用于您的示例:

您的第一个 eta-reduction 示例将(lambda (x) (M x)) 转换为M,其中xM 中不是免费的。 Eta-expansion 是相反的,所以它将M 转换为(lambda (x) (M x)),你必须选择一个xM 中不是免费的。

您的第二个 eta-reduction 示例将 (lambda (x) ((lambda (y) (y y)) x)) 转换为 (lambda (y) (y y))。同样 eta-expansion 是相反的,所以如果给定 (lambda (y) (y y)),它将产生 (lambda (x) ((lambda (y) (y y)) x))

你的第三个例子是不同的。您正在尝试对 (lambda (y) (y y)) 进行 eta-expand,根据第二个示例应该生成 (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))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-20
    • 2020-01-21
    • 1970-01-01
    相关资源
    最近更新 更多