【发布时间】:2015-12-16 13:19:38
【问题描述】:
让我们考虑以下 Continuation monad 的实现,用于 CPS 样式的计算产生和整数:
module Cont : sig
type 'a t = ('a -> int) -> int
val return : 'a -> 'a t
val bind : 'a t -> ('a -> 'b t) -> 'b t
val callCC: (('a -> 'b t) -> 'a t) -> 'a t
end = struct
type 'a t = ('a -> int) -> int
let return x =
fun cont -> cont x
let bind m f =
fun cont -> m (fun x -> (f x) cont)
let callCC k =
fun cont -> k (fun x -> (fun _ -> cont x)) cont
end
我们如何重写 gcd 计算的 CPS 风格的实现(参见 How to memoize recursive functions?),尤其是利用 Cont monad 的记忆?
定义后
let gcd_cont k (a,b) =
let (q, r) = (a / b, a mod b) in
if r = 0 then Cont.return b else k (b,r)
我尝试使用类型求解器来提示我记忆函数应该具有的类型:
# let gcd memo ((a,b):int * int) =
Cont.callCC (memo gcd_cont (a,b)) (fun x -> x)
;;
val gcd :
(((int * int -> int Cont.t) -> int * int -> int Cont.t) ->
int * int -> (int -> 'a Cont.t) -> int Cont.t) ->
int * int -> int = <fun>
但是我无法将这个提示转化为实际的实现。有人能做到这一点吗?在记忆函数中使用“callCC”背后的逻辑是,如果在缓存中找到一个值,那么这是一个提前退出条件。
【问题讨论】:
标签: ocaml monads continuations