Ocaml 有可能保证回忆录的一致性吗?

Ocaml 有可能保证回忆录的一致性吗?,ocaml,lazy-evaluation,memoization,mutable,side-effects,Ocaml,Lazy Evaluation,Memoization,Mutable,Side Effects,我想构建一个带有记忆功能的模块I。类型I.t包含真正复杂的内容c,以及一些可变属性(例如,mutable很酷)。该模块为外部提供了计算和获取属性的函数(例如,is_cool),这可能成本高昂,这就是使用可变属性的原因: (*in i.ml *) module Content = struct type t = { i: int; mutable j: int } let is_cool (x: t) : bool = ... end module I : sig type t

我想构建一个带有记忆功能的模块
I
。类型
I.t
包含真正复杂的内容
c
,以及一些可变属性(例如,
mutable很酷
)。该模块为外部提供了计算和获取属性的函数(例如,
is_cool
),这可能成本高昂,这就是使用可变属性的原因:

(*in i.ml *)
module Content = struct
  type t = { i: int; mutable j: int }
  let is_cool (x: t) : bool = ...
end

module I : sig
  type t
  val get_c: t -> Content.t
  val is_cool: t -> bool
  ...
end = struct 
  type t = {
     c : Content.t; 
     mutable is_cool : bool option;
     mutable property_a : int option }

  let get_c (x: t) -> Content.t = x.c

  let is_cool (x: t) : bool = 
    match x.is_cool with
    | Some r -> r
    | None -> (* not yet calculated *)
       let r = Content.is_cool x.c in
       x.is_cool <- Some r;
       r
  end
  ...
然而,禁止这一代码似乎并不容易,因为它改变了内容:

(* in main.ml *)
let test (x: I.t) (i_new: int) =
  let c = I.get_c x in
  let c_new = { c with Content.i = i_new } in
  let y = { x with c = c_new } in 
  (* now the content and the properties in y are likely to be inconsistent *) 
一种改进方法是在模块
I
中添加
set
,并始终在
{x with c=c_new}
处使用
set x c_new

(*in i.ml *)
let set (x: t) (c: Content.t) : t = 
  { c = c; is_cool = None; property_a = None }
但是还存在一些问题,比如,

1) 仍然不可能禁止人们编写
{x with c=c_new}

2) 修改
Content.t
中的可变组件(例如,
mutable j:int
)也会使
I.t
不一致:

(* in main.ml *)
let test (x: I.t) (j_new: int) =
  let c = I.get_c x in
  c.Content.j <- j_new; 
  (* now the content and the properties in x are likely to be inconsistent *) 
(*在main.ml*中)
let测试(x:I.t)(j_new:int)=
设c=I,得到x

c、 Content.j嗯,你可以使用private

您的代码如下所示:

module type C = sig
  type t = private { i: int; mutable j: int }
  val new_c : int -> int -> t
  val is_cool : t -> bool
end
module Content : C = struct
  type t = { i: int; mutable j: int }
  let new_c = ...
  let is_cool (x: t) : bool = ...
end

module I : sig
  type t
  val new_i : int -> int -> t
  val get_c: t -> Content.t
  val is_cool: t -> bool
  ...
end = struct 
  type t = {
     c : Content.t; 
     mutable is_cool : bool option;
     mutable property_a : int option }

  let new_i = ...

  let get_c (x: t) -> Content.t = x.c

  let is_cool (x: t) : bool = 
    match x.is_cool with
    | Some r -> r
    | None -> (* not yet calculated *)
       let r = Content.is_cool x.c in
       x.is_cool <- Some r;
       r
  end
  ...
它将拒绝您回答:

 Error: Cannot create values of the private type Content.t
 let c = {i = 3; j = 3};;
 Error: Cannot create values of the private type Content.t