我想用memoization构建一个模块Integer id = hibSession.save(record);
Record createdRecord = hibSession.get(Record.class,id);
return createdRecord
。类型I
包含真实的复杂内容I.t
和一些可变属性(例如c
)。该模块为外部提供了计算和获取属性的函数(例如mutable is_cool
),这可能代价高昂,这就是使用可变属性的原因:
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
...
和外部代码,以便在整个程序执行期间对于任何类型I
的值,其可变属性始终与其内容一致I.t
。一致意味着“可变属性应为c
或None
,其中Some v
表示内容的当前属性。”
例如,模块v
的签名禁止以下代码直接修改属性:
I.t
但是,似乎要禁止更改内容的代码并不容易:
(* in main.ml *)
open I
let test (x: I.t) =
x.is_cool <- Some false
改善此问题的一种方法是在模块(* 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 *)
中添加set
,并始终在I
处使用set x c_new
:
{ x with c = c_new }
然而,仍有问题,例如,
1)仍然无法禁止人们撰写(*in i.ml *)
let set (x: t) (c: Content.t) : t =
{ c = c; is_cool = None; property_a = None }
2)对{ x with c = c_new }
中可变组件的修改(例如,Content.t
)也会使mutable j: int
不一致:
I.t
有没有人知道任何现有的反思或解决方案面临因记忆造成的这种不一致?如果我们总是在“record with”的地方使用(* 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 *)
,并且不允许set
中的可变组件,我们能否保证100%的任何代码方案的一致性?
答案 0 :(得分:0)
好吧,你可以使用私人
您的代码如下所示:
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
...
如果你试着写:
let c = {i = 3; j = 3};;
它会拒绝你回答:
Error: Cannot create values of the private type Content.t