我是 ocaml 的新手,并尝试编写一个延续传递样式函数,但很困惑我需要将什么值传递给 k 上的附加参数
例如,我可以编写一个递归函数,如果列表的所有元素都是偶数,则返回 true,否则返回 false。
所以它就像
let rec even list = ....
在 CPS 上,我知道我需要添加一个参数来传递函数
很喜欢
let rec evenk list k = ....
但我不知道如何处理这个 k 以及这究竟是如何工作的
例如对于这个偶数功能,环境看起来像
val evenk : int list -> (bool -> ’a) -> ’a = <fun>
evenk [4; 2; 12; 5; 6] (fun x -> x) (* output should give false *)
最佳答案
续集k
是一个从 evenk
获取结果的函数并执行“其余的计算”并产生“答案”。答案的类型以及“其余计算”的含义取决于您使用 CPS 的目的。 CPS 通常本身并不是目的,而是出于某种目的而完成的。例如,在 CPS 形式中,很容易实现控制运算符或优化尾调用。在不知道您要完成什么的情况下,很难回答您的问题。
对于它的值(value),如果您只是尝试从直接样式转换为继续传递样式,并且您关心的只是答案的值,那么传递恒等函数作为继续是正确的。
一个好的下一步是实现 evenk
使用 CPS。我会做一个更简单的例子。
如果我有直接式功能
let muladd x i n = x + i * n
如果我假设 CPS 原语
mulk
和 addk
,我可以写let muladdk x i n k =
let k' product = addk x product k in
mulk i n k'
你会看到乘法首先完成,然后它“继续”与
k'
,它进行加法,最后是 continues
与 k
,返回给调用者。关键思想是在muladdk
的主体内我分配了一个新的延续 k'
它代表乘加函数中的中间点。使您的evenk
您必须至少分配一个这样的延续。我希望这有帮助。
关于recursion - Ocaml 延续传球风格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3072946/