13
为无类型的lambda演算编写解释器
面临的挑战是为无类型lambda演算编写尽可能少的字符的解释器。我们将无类型的lambda演算定义如下: 句法 有以下三种表达式: Lambda表达式的形式为(λ x. e),其中x可以是任何合法变量名和e任何合法表达式。这里x称为参数,e称为函数体。 为简单起见,我们添加了进一步的限制,即不得存在与x当前作用域同名的变量。当变量的名称出现在(λ和之间时,变量就开始在范围.内,而在对应的变量处就停止在范围内)。 功能应用程序具有形式和形式(f a),它们是合法的表达式。这里称为函数,称为参数。fafa 变量的格式为xwhere x是合法变量名。 语义学 通过将函数体内参数的每次出现替换为其自变量来应用函数。更正式的形式的表达((λ x. e) a),其中x是变量名和e和a是表达式,评估(或减少)至表达式e',其中e'是取代的每次出现的结果x在e与a。 范式是无法进一步评估的表达式。 挑战 您的任务(如果您选择接受它)是编写一个解释器,该解释器将不包含自由变量的未类型化lambda演算的表达式作为输入,并产生该表达式的标准形式(或与该表达式一致的表达式)作为其输出。 。如果该表达式没有范式或它不是有效的表达式,则该行为是不确定的。 字符数最少的解决方案获胜。 一些注意事项: 输入既可以从stdin读取,也可以从作为命令行参数给出的文件名读取(您只需要实现一个或另一个即可-无需同时实现)。输出进入标准输出。 或者,您可以定义一个函数,该函数将输入作为字符串,然后将输出作为字符串返回。 如果非ASCII字符对您有问题,则可以使用反斜杠(\)字符代替λ。 我们计算字符数,而不是字节数,因此,即使您的源文件被编码为unicodeλ也算为一个字符。 合法变量名称由一个或多个小写字母组成,即a和z之间的字符(无需支持字母数字名称,大写字母或非拉丁字母-尽管这样做当然不会使您的解决方案无效)。 就此挑战而言,没有括号是可选的。每个lambda表达式和每个函数应用程序都将恰好由一对括号包围。变量名不会用括号括起来。 语法糖就像写(λ x y. e)的(λ x. (λ y. e))并不需要得到支持。 如果评估函数的递归深度大于100,则行为不确定。该值应该足够低,以至于无需在所有语言中进行优化即可实现,而且还应足够大以能够执行大多数表达式。 您可能还假定间距将与示例中的相同,即在输入的开头和结尾或a λ或之前没有空格,而在a .和之后.以及函数与其参数之间以及a 之后恰好有一个空格λ。 样本输入和输出 输入: ((λ x. x) (λ y. (λ z. …