使用简单的纯函数语言实现折叠而不进行惰性求值

时间:2012-04-15 22:10:08

标签: function haskell recursion lazy-evaluation fold

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

enter image description here

它相当于下面的方案定义(虽然我的'语言'不是Scheme,但它是图表)

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

问题在于,由于没有特殊的运算符,所有内容,特别是if只是一个正常的函数。在这种形式中,程序永远不会终止,而是达到最大堆栈深度,因为始终会计算else子句。

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

2 个答案:

答案 0 :(得分:2)

我认为在粘合剂下评估(特别是评估lambdas的体)是非常罕见的,所以我认为使用严格语言的标准解决方案是引入lambda。我不知道方案语法,但是在Haskell语法中,如果你希望x是一个严格函数f的惰性参数,你可能会写f (\() -> x)之类的东西(并修改f恰当地期待这样的lambdas,并在你想要解除它们的时候打电话给他们。)

答案 1 :(得分:1)

您可以将if-expression的两个分支编译为thunk,并根据条件调用相应的thunk。如果以这种方式编写方案的正式定义,我不会感到惊讶。