"延续"在函数式编程中意味着什么?(特别是SML)

Ral*_*lph 4 recursion continuations functional-programming sml smlnj

我已经阅读了很多关于延续和我看到的非常常见的定义,它返回控制状态.

我正在学习SML教授的函数式编程课程.

我们的教授定义了延续:

"什么跟踪我们仍然需要做的事情"; "让我们控制调用堆栈"

他的很多例子都围绕着树木.在本章之前,我们做了尾递归.我知道尾递归允许堆栈通过额外的参数"构建"答案来保存递归调用的函数.反转列表将在新的累加器中构建,我们会相应地附加到它.此外,他说有关函数的事情被调用(但没有评估),除非我们到达我们向后替换的末尾.他说尾部递归的改进版本将使用CPS(Continuation Programming Style).

有人可以简单解释一下延续是什么以及为什么它们比其他编程风格更受青睐?

我找到了这个帮助我的stackoverflow链接,但仍然没有为我澄清这个想法:

我只是没有得到延续!

Reu*_*amp 7

Continuations简单地将"接下来会发生什么"视为可以无条件地使用一次,忽略其他内容或多次使用的第一类对象.

要解决Continuation Passing Style的问题,这里有一些正常写的表达式:

let h x = f (g x)
Run Code Online (Sandbox Code Playgroud)

g应用于x并f应用于结果.请注意,g没有任何控制.无论如何,它的结果都会传递给f.

在CPS中这是写的

let h x next = (g x (fun result -> f result next))
Run Code Online (Sandbox Code Playgroud)

g不仅有x作为参数,而且是一个继续,它接受g的输出并返回最终值.此函数f以相同的方式调用,并next作为延续.

发生了什么?改变了什么让它变得如此有用f (g x)?不同之处在于现在g处于控制之中.它可以决定是否使用接下来发生的事情.这是延续的本质.

连续出现的示例是命令式编程语言,其中您具有控制结构.Whiles,block,普通语句,break和continue都是通过continuation来概括的,因为这些控制结构接下来会发生什么,并决定如何处理它,例如我们可以

...
while(condition1) {
    statement1;
    if(condition2) break;
    statement2;
    if(condition3) continue;
    statement3;
}
return statement3;
...
Run Code Online (Sandbox Code Playgroud)

while,block,statement,break和continue都可以通过continuation在功能模型中描述.每个构造都可以被认为是接受该构造的函数

  • 当前环境包含
    • 封闭的范围
    • 接受当前环境并返回延续的可选函数
      • 从最内圈回来
      • 继续从内心循环
      • 从当前函数返回.
  • 与之关联的所有块(if-blocks,while-block等)
  • 继续下一个陈述

并返回新环境.

在while循环中,根据当前环境评估条件.如果将其评估为true,则评估该块并返回新环境.返回使用新环境再次评估while循环的结果.如果将其计算为false,则返回评估下一个语句的结果.

使用break语句,我们在环境中查找break函数.如果没有找到函数,那么我们不在循环中,我们给出错误.否则,我们将当前环境提供给函数并返回已计算的continuation,这将是while循环之后的语句.

使用continue语句会发生同样的情况,除了continuation将是while循环.

使用return语句,continuation将是调用当前函数之后的语句,但它会从环境中删除当前的封闭范围.