【问题标题】:product of list using continuation使用延续的列表的产品
【发布时间】:2019-05-12 23:54:28
【问题描述】:

我的目标是编写一个int list -> int 类型的时间函数,它接受ints 的列表,使用延续,返回一个int,这样int = int list 中所有 ints 的乘法。 例如times [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) ;; 

我的代码有问题

  1. 它返回一个int列表,其中一个元素是结果(输入int list中所有ints的乘法)

  2. 我觉得这并没有真正使用延续,这似乎是一个正常的尾递归函数,但我不确定,因为我对这种编程风格还不是很熟悉。

【问题讨论】:

  • 我完全看不出你怎么能用这种类型的函数来实现 CPS。我认为应该改为int list -> (int -> unit) -> unit
  • 哦,对不起,我认为任何可以以 tail_recursive 方式编写的函数都可以使用 CPS 重写:o 这不是真的吗?
  • CPS 通过延续传递“返回”值,这意味着函数返回,至少在 CPS 的上下文中。要让外部函数正常返回值,您必须通过整个“CPS”调用链返回该值,这意味着它不是 CPS,只是尾递归。
  • 确实可以将任何尾递归函数重写为CPS,但不能不更改类型签名。
  • 在延续传递风格中,函数不会像我们在默认风格中那样“返回”。

标签: ocaml multiplication continuations continuation-passing


【解决方案1】:

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

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 和直接风格之间差异的示例(在 Wikipedia 中以"Continuation-passing style" 编写)可能会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-04
    • 2014-08-14
    相关资源
    最近更新 更多