Ocaml 使用延续的列表乘积

Ocaml 使用延续的列表乘积,ocaml,multiplication,continuations,continuation-passing,Ocaml,Multiplication,Continuations,Continuation Passing,我的目标是编写一个类型为int list->int的times函数,它获取一个ints的列表,并使用continuations返回一个int,这样int=int列表中所有int的乘法。 例如次[2;2;3]返回12 以下是我到目前为止的情况: let times l = let rec times' l c = match l with | [] -> c [] | h::h2::t -> times' (h*h2::t) (fun r -> c ( r)) | h

我的目标是编写一个类型为
int list->int
的times函数,它获取一个
int
s的列表,并使用continuations返回一个
int
,这样
int
=int列表中所有
int
的乘法。 例如
次[2;2;3]
返回
12

以下是我到目前为止的情况:

let times l = 
 let rec times' l c = match l with
 | [] -> c []
 | h::h2::t -> times' (h*h2::t) (fun r -> c ( r))
 | h :: [] -> times' [] (fun r -> c (h::[]))
 in
  times' l (fun r -> r) ;; 
我的代码有问题

  • 它返回一个整数列表,其中一个元素是结果(将输入的
    int列表中的所有
    int
    s相乘)

  • 我觉得这不是真正使用continuations,这似乎是一个正常的尾部递归函数,但我不确定,因为我仍然不太熟悉这种编程风格


  • 您以递归调用的方式在参数中进行计算,但应该在继续中进行。对于CP,您应该做的是“增长”给定的延续

    let times l =
      let rec aux l c =
        match l with
        | [] -> c 1  (* I assume that (times []) is one, and pass it to the next computation c. *)
        | n::ns -> aux ns (fun x -> c (n * x))  (* In a new continuation: For a given value x, multiply by n, and pass it to the next computation c. *)
      in aux l (fun r -> r)
    

    此外,维基百科中编写的解释CPS和direct样式之间差异的示例可能会有所帮助。

    我看不出您如何能够用这种类型的函数实现CPS。我认为应该改为
    int list->(int->unit)->unit
    。哦,对不起,我认为任何可以用tail\u递归方式编写的函数都可以用CPS重新编写:o那么这不是真的吗?CPS通过continuation传递“return”值,这意味着函数不返回,至少在CPS的背景下。要让外部函数正常返回值,您必须通过整个“CPS”调用链返回该值,这意味着它不是CPS,只是尾部递归。应该可以将任何尾部递归函数重写为CPS,但不能不更改类型签名。在延续传递样式中,函数不“返回”就像我们在默认样式中所做的那样。