【问题标题】:Understanding the implementation of Y-Combinator了解 Y-Combinator 的实现
【发布时间】:2019-04-28 17:39:39
【问题描述】:

我想详细了解一下我们是如何从 Y-combinator 的 lambda 演算表达式中得到的:

Y = λf.(λx.f (x x)) (λx.f (x x))

到以下实现(在 Scala 中):

def Y[A, B](f: (A => B) => A => B): A => B = (x: A) => f(Y(f))(x)

我对函数式编程很陌生,但我对 lambda 演算以及替换过程的工作原理有相当的了解。然而,我很难理解我们是如何从正式表达到实现的。

此外,我很想知道如何告诉我的函数的类型和数量 参数及其返回类型 的任何 lambda?

【问题讨论】:

  • 你在哪里找到了实现?通过直接在 Y 中递归看起来像是“作弊”。

标签: scala recursion functional-programming lambda-calculus y-combinator


【解决方案1】:

首先,Scala 代码的写法很长:

def Y[A, B](f: (A => B) => A => B): A => B = f(Y(f))

这里,f 被部分应用。 (看起来代码作者选择使用 lambda 来使其更明确。)

现在,我们如何得出此代码? Wikipedia notes 那个Y f = f (Y f)。将此扩展为类似 Scala 的东西,我们有 def Y(f) = f(Y(f))。这不能作为 lambda 演算中的定义,它不允许直接递归,但它在 Scala 中有效。为了使它成为有效的 Scala,我们需要添加类型。将类型添加到 f 会导致:

def Y(f: (A => B) => A => B) = f(Y(f))

由于A 和B 是免费的,我们需要将它们设为类型参数:

def Y[A, B](f: (A => B) => A => B) = f(Y(f))

由于是递归的,我们需要添加一个返回类型:

def Y[A, B](f: (A => B) => A => B): A => B = f(Y(f))

【讨论】:

  • 感谢您的回答。我也很想知道我们是如何推断 f 是 (A => B) => A => B 类型的?
  • 你确定@ecdhe 的版本和你的不一样吗?在按值调用设置中,eta-reduction 确实会改变语义。我不认为这个版本应该工作,除非你在右边的 Y 内进行 eta-expand。
【解决方案2】:

请注意,您编写的不是Y 组合器的实现。 “Y 组合子”是 λ 演算中的特定“定点组合子”。术语g 的“定点”只是一个点x,这样,

g(x) = x 

“定点组合器”F 是可用于“产生”定点的术语。也就是说,这样,

g(F(g)) = F(g)

Y = λf.(λx.f (x x)) (λx.f (x x)) 一词是遵守该等式的众多术语之一,即g(Y(g)) = Y(g) 在某种意义上可以将一个术语简化为另一个。此属性意味着此类术语,包括Y,可用于在微积分中“编码递归”。

关于输入注意,Y 组合子不能在简单输入的 λ-演算中输入。甚至在系统 F 的多态微积分中也没有。如果你尝试输入它,你会得到一种“无限深度”。要键入它,您需要在类型级别进行递归。因此,如果您想扩展例如只需将 λ-calculus 键入您提供的小型函数式编程语言 Y 作为原语。

不过,您没有使用 λ-演算,而且您的语言已经带有递归。所以你写的是Scala中定点“组合器”的简单定义。直截了当,因为定点(几乎)紧跟定义。

Y(f)(x) = f(Y(f))(x)

对于所有x 都是正确的(并且它是一个纯函数),因此,

Y(f) = f(Y(f))

这是定点方程。关于Y 类型的推断,考虑方程Y(f)(x) = f(Y(f))(x) 并让,

f : A => B
Y : C => D 

既然Y : C => D 将f : A => B 作为输入,那么

C = A => B

因为Y f : D 是f : A => B 的输入,那么

D = A

由于Y f : D的输出与f(Y(f)) : B的输出相同,那么

D = B

到目前为止,

Y : (A => A) => A 

由于Y(f)被应用到x,Y(f)是一个函数,所以

A = A1 => B1 

对于某些类型 A1 和 B1 ,因此,

Y : ((A1 => B1) => (A1 => B1)) => A1 => B1

【讨论】:

  • 很好的答案!谢谢。
  • 很好的答案。我特别喜欢你写作的精确性:“无限深度的类型”精确而清晰,通常的“无限类型”令人困惑和模糊。
猜你喜欢
  • 1970-01-01
  • 2016-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-01
  • 1970-01-01
相关资源
最近更新 更多