我是ocaml和tryin的新手,可以编写一个连续传递样式函数,但是很困惑我需要将什么值传递给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),如果您只是尝试从直接样式转换为通过延续的样式,而您关心的只是答案的值,那么通过身份函数作为延续是正确的。

下一步是使用CPS实现evenk。我将做一个简单的例子。
如果我有直接样式功能

let muladd x i n = x + i * n

如果我假设CPS原语mulkaddk,我可以编写
let muladdk x i n k =
  let k' product = addk x product k in
  mulk i n k'

您会看到,首先完成了多重复制,然后继续执行k'(执行添加操作),最后完成了continuesk的操作,然后返回给调用者。关键思想是,我在muladdk主体内分配了一个新的连续k',它表示乘加函数中的中间点。为了使evenk正常工作,您将必须分配至少一个这样的延续。

我希望这有帮助。

10-07 21:01