无类型Lambda演算的功能语言

时间:2011-10-25 13:52:36

标签: compiler-construction functional-programming interpreter lambda-calculus untyped-variables

是否有无类型lambda演算的解释器(或编译器)? (根据this thread它是可能的。)我认识到它作为一种编程语言几乎没用,特别是如果实现了大部分语言(例如数字和布尔运算符)(由用户或通过图书馆)在语言本身。但是,我仍然认为这对学习和探索微积分很有用。对于这个,解释器比编译器更可取,因为它们可以工作。有谁知道这样的节目?

7 个答案:

答案 0 :(得分:7)

您可以使用任何具有lambda抽象的无类型语言。例如Python或JavaScript。主要有两个缺点:

  1. 这些语言没有延迟评估。这意味着并非所有lambda术语都会收敛,即使它们具有正常形式。您必须考虑到这一点并相应地修改任务。
  2. 您不会将结果视为普通形式的lambda术语。您必须知道对结果的期望,并使用该语言将其评估为可以显示的内容。
  3. 知道了这一点,让我们在Python中做一个例子: 首先,我们创建辅助函数以在数字和教会数字之间进行转换:

    # Construct Church numeral from an integer
    def int2church(n):
        def repeat(f, m, x):
            if (m == 0): return x
            else: return f(repeat(f, m-1, x))
        return lambda f: (lambda x: repeat(f, n, x))
    
    def church2int(l):
        return l(lambda x: x + 1)(0)
    

    现在我们可以在数字上定义标准操作:

    zero = int2church(0)
    one = int2church(1)
    
    pred = lambda n: lambda f: lambda x: n(lambda g: lambda h: h(g(f)))(lambda u: x)(lambda u: u)
    
    mul = lambda m: lambda n: (lambda f: m(n(f)))
    
    expn = lambda n: lambda m: m(n)
    
    tetra = lambda n: lambda m: m(expn(n))(one)
    

    并计算例如 4 3

    expn = lambda n: (lambda m: m(n))
    
    a = int2church(4)
    b = int2church(3)
    print church2int(expn(a)(b))
    

    tetration

    a = int2church(5)
    b = int2church(2)
    print church2int(tetra(a)(b))
    

    为了能够表达更有趣的东西,我们可以定义Y组合器:

    y = lambda f: (lambda x: f(lambda v: x(x)(v))) (lambda x: f(lambda v: x(x)(v)))
    

    并计算例如阶乘:

    true = lambda x: (lambda y: x)
    false = lambda x: (lambda y: y)
    
    iszero = lambda n: n(lambda x: false)(true)
    
    fact = y(lambda r: lambda n: iszero(n)(one)(mul(n)(lambda x: r(pred(n))(x))))
    print church2int(fact(int2church(6)))
    

    请注意,Y组合器必须使用η-expansion进行严格评估,并使用因子函数来避免由于严格评估而产生的无限递归。

答案 1 :(得分:6)

本杰明·皮尔斯提供implementationsuntypedλ-微积分simply-typed伴随他的教科书Types and Programming Languages。它们是用OCaml编写的,包含示例定义。然而,为简单的λ-calculi编写解释器或编译器并不困难。

答案 2 :(得分:3)

使用一些技巧,几乎可以在任何函数语言中使用。至少我在Haskell和OCaml中看到过类似的东西。但有时你必须绕过类型系统的限制。通常,您通过将其实现为统一系统来获得“无类型”功能。所以每个lambda函数都有

类型
type lambda = lambda -> lambda

在默认设置中,例如OCaml将不允许这样的递归类型,但这可以通过定义来规避:

type lambda = L of lambda -> lambda

答案 3 :(得分:3)

我是函数式编程课程的助教。出于教学目的,我们在网上看到lambda calculus reducer这是一个有趣且有用的工具来探索微积分。如果你想玩它们,它们也有可用的SML源代码。

答案 4 :(得分:2)

我在今年早些时候写过一篇。 Here it is

答案 5 :(得分:1)

我为基于lambda演算的语言创建了一个web hosted interpreter,我称之为pureƒn,以便学习Lambda微积分的工作原理。对于希望以最小符号复杂性以交互方式学习和体验计算机科学的一些基本原理的人来说,这可能是有用的。

pureƒn是一个基于Lambda微积分功能的编程环境,但有一个简化的表示法。 pureƒn允许定义,应用和减少功能抽象。符号和语法很小但足以让底层概念易于理解。

底层编译器是用Python编写的,并将抽象编译成函数,这些函数在应用于彼此时会自动缩减为正常形式(如果可能)。这意味着如果定义S,K和I组合子函数,然后将它们应用为SKK,则返回的函数将是I函数,而不仅仅是一个像I一样的函数,这意味着以下内容将成立:

>>>S(K)(K) is I
True

答案 6 :(得分:0)

Here是用Python编写的。它似乎非常不成熟,但它是实现一个Python的有趣开端。这取决于模块ply

Here是C ++的另一种(非常有趣)。

如果您的主要目的是为了学习lambda演算(例如,尝试为自己推导算术运算)以及特定的教会数字和布尔值而获得一些基本的自动化,一个原始但易于实现的解决方案是限制自己到Python的一小部分,您可以在其中定义自己的教会数字和运算符,并通过将它们转换为常规Python类型的函数进行检查。教会数字的功能:

lambda churchnum: churchnum(lambda x: x+1)(0)

一个教会布尔人:

lambda churchbool: churchbool(True)(False)