我的目标是编写一个int list -> int
类型的时间函数,该函数接受int
的列表,并使用延续,返回一个int
int
= int
中所有int list
的乘积。
例如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) ;;
我的代码存在问题
它返回一个int列表,其中有一个元素是结果(输入的int
中所有int list
的乘法)
我觉得这不是真的使用延续,这似乎是正常的尾部递归函数,但是我不确定,因为我对这种编程风格还不是很熟悉。
答案 0 :(得分: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)
此外,用Wikipedia中的"Continuation-passing style"编写的解释CPS和直接样式之间差异的示例也可能会有所帮助。