Chúng ta hãy xem xét việc thực hiện sau đây của đơn nguyên Tiếp tục, cho phép tính CPS-phong cách năng suất và số nguyên:Làm thế nào để chuyển đổi tính toán CPS kiểu gcd sử dụng Tiếp tục Monad
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
Làm thế nào chúng ta có thể viết lại CPS- thực hiện phong cách tính toán gcd (xem How to memoize recursive functions?) và đặc biệt là việc ghi nhớ để tận dụng lợi thế của Cont monad?
Sau khi xác định
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)
Tôi cố gắng để sử dụng các loại giải để cho tôi gợi về loại rằng chức năng memoization nên có:
# 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>
Tuy nhiên tôi không thể quay gợi ý này thành một thực hiện thực tế. Có ai đó có thể làm điều này không? Logic đằng sau việc sử dụng "callCC" trong chức năng ghi nhớ là nếu một giá trị được tìm thấy trong bộ đệm, thì đây là điều kiện thoát sớm.
Điều xấu của tôi khi đặt tên cho CPS là không. Có bất kỳ tên hợp quy nào cho dạng cụ thể của phiên bản chức năng "có thể điều khiển được" của các chức năng không? –