【问题标题】:Implementing fold in simple purely functional language without lazy evaluation用简单的纯函数式语言实现折叠,无需惰性求值
【发布时间】:2012-04-27 08:07:12
【问题描述】:

我正在尝试实现一种用于自动程序合成的简单函数式语言。 数据结构是函数和值的图,可编译为 javascript。 下图应该是一个折叠函数。 funcApp 节点连接到一个函数节点和多个值节点,并将函数应用于值。 arg0 是列表,arg1 是初始值 (z) arg2 是要应用的函数。

相当于下面的scheme定义(虽然我的'语言'不是Scheme,是图)

(define (foldr f z xs)
   (if (null? xs)
       z
       (f (car xs) (foldr f z (cdr xs)))))

问题是因为没有特殊的操作符,所以一切,特别是if 只是一个普通的函数。在这种形式下,程序永远不会终止,而是会达到最大堆栈深度,因为 else 子句总是被计算。

我认为这个问题在某些语言中是通过惰性求值解决的。所以我的问题是:是否有没有这种无限递归的功能版本的 fold 2)如果有必要,从哪里开始考虑将惰性求值应用于这样的简单语言。

【问题讨论】:

  • if 是 Scheme 中的一种特殊形式,因此 else 表达式总是 not 被计算。这里有什么问题?
  • 我知道Scheme就是这种情况,我想我在最后一段中非常明确地陈述了我的问题
  • 第一个问题没看懂。 2) 的答案是“特别处理 if”。
  • @zenna:首先,非严格不等于懒惰。其次,Scheme 通过与其他函数调用不同的方式处理 if 来解决这个问题(这称为特殊形式)。您不需要像 Haskell 那样进行全面的惰性评估(尽管您可以将 if-then-else 实现为 Haskell 中的一个简单函数)。 sepp 说如果你没有懒惰的if 就不能写fold 的声明并不完全正确(他已经删除了该评论):你可以通过向if 提供lambdas 来模拟这种行为并调用结果。
  • 顺便说一句,我的困惑主要来自于您提出的“方案”示例实际上不是方案 :)

标签: function haskell recursion lazy-evaluation fold


【解决方案1】:

您可以将 if 表达式的两个分支编译为 thunk,并根据条件调用适当的 thunk。如果 scheme 的正式定义是这样写的,我不会感到惊讶。

【讨论】:

    【解决方案2】:

    我认为在活页夹下进行评估(尤其是评估 lambda 的主体)非常罕见,因此我认为延迟严格语言的标准解决方案是引入 lambda。我不知道方案语法,但在 Haskell 语法中,如果您希望 x 成为严格函数 f 的惰性参数,您可以编写类似 f (\() -> x) 的内容(并适当修改 f 以期望这样的 lambda,并在你想取消它们的时候调用它们)。

    【讨论】:

    • Scheme 语法与 Haskell 语法非常相似,(λ () x) 是一个 thunk,并且在括号中“调用”它,例如(someThunk)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    • 2019-11-16
    • 2012-01-05
    • 2020-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多