Reference 具有存储的模块
经常发生的情况是,从一个值计算一个属性的成本很高。因此,在计算属性后,最好能够存储该属性。我想知道如何正确地编写代码 让我们举个例子。假设我们有一个整数类型,通常我们需要计算这种类型的值的素数因子(假设负整数的素数因子是Reference 具有存储的模块,reference,ocaml,record,Reference,Ocaml,Record,经常发生的情况是,从一个值计算一个属性的成本很高。因此,在计算属性后,最好能够存储该属性。我想知道如何正确地编写代码 让我们举个例子。假设我们有一个整数类型,通常我们需要计算这种类型的值的素数因子(假设负整数的素数因子是None): 目前,get_prime_factors只调用calculate_prime_factors,因此,pf_1、pf_2、pf_3的所有计算都非常耗时。我希望有一种机制能够在模块内存储素数因子,这样只要整数不改变,get\u prime\u factors的第二次和第
None
):
目前,get_prime_factors
只调用calculate_prime_factors
,因此,pf_1
、pf_2
、pf_3
的所有计算都非常耗时。我希望有一种机制能够在模块内存储素数因子,这样只要整数不改变,get\u prime\u factors
的第二次和第三次就可以读取存储的内容
有人知道如何修改模块I
来实现这一点吗
我们可能需要引用使这种机制成为可能(例如,
let vr=ref(I.C 100)in…
)。我可以使用参考资料。但是如果保持值(即,!vr
)发生更改,我不知道如何自动触发计算素数因子。
。我将执行以下操作:
let get_prime_factors x =
match get x with
| None ->
let res = calculate_prime_factors x
in
begin
set x res ;
res
end
| Some res -> res
;;
您需要一个可由get
和set
访问的可变数据结构。例如,列表上有一个引用(但您可能更喜欢哈希表):
您也可以使用异常而不是
选项
类型(None
和Some
)。我将执行以下操作:
let get_prime_factors x =
match get x with
| None ->
let res = calculate_prime_factors x
in
begin
set x res ;
res
end
| Some res -> res
;;
您需要一个可由get
和set
访问的可变数据结构。例如,列表上有一个引用(但您可能更喜欢哈希表):
您也可以使用异常而不是选项
类型(None
和Some
)
你可以试试这个:
module I =
struct
type t = C of int
type pf = (int list) option
let calculate_prime_factors (x: t) : pf =
(* a costly function to calculate prime factors *)
... ...
module HI = Hashtbl.Make (struct
type t = C of int
let equal = (=)
let hash (C x) = x
end)
let get_prime_factors =
let h = Hashtbl.create 17 in
fun x ->
try Hashtbl.find h x
with
Not_found -> let pf = calculate_prime_factors x in
Hashtbl.add h x pf;
pf
end
let () =
let v = I.C 100 in
let pf_1 = I.get_prime_factors v in
let pf_2 = I.get_prime_factors v in
let pf_3 = I.get_prime_factors v in
...
您可以将其调整为负整数(例如,有例外,这比选项更好),但我希望您能理解。您想做的是,不
你可以试试这个:
module I =
struct
type t = C of int
type pf = (int list) option
let calculate_prime_factors (x: t) : pf =
(* a costly function to calculate prime factors *)
... ...
module HI = Hashtbl.Make (struct
type t = C of int
let equal = (=)
let hash (C x) = x
end)
let get_prime_factors =
let h = Hashtbl.create 17 in
fun x ->
try Hashtbl.find h x
with
Not_found -> let pf = calculate_prime_factors x in
Hashtbl.add h x pf;
pf
end
let () =
let v = I.C 100 in
let pf_1 = I.get_prime_factors v in
let pf_2 = I.get_prime_factors v in
let pf_3 = I.get_prime_factors v in
...
您可以将其调整为负整数(例如,有例外,这比选项更好),但我希望您能理解。看起来,您正在寻找以下解决方案:
module I = struct
type t = {
c : int;
mutable result : int option;
}
let create c = {c; result = None}
let calculate_prime_factors t = match t.result with
| Some r -> r
| None ->
let r = do_calculate t.c in
t.result <- Some r;
r
end
看起来,您正在寻找此解决方案:
module I = struct
type t = {
c : int;
mutable result : int option;
}
let create c = {c; result = None}
let calculate_prime_factors t = match t.result with
| Some r -> r
| None ->
let r = do_calculate t.c in
t.result <- Some r;
r
end
感谢您的解决方案,它将整数对及其素数因子存储在外部。它应该可以工作,但我正在寻找一种将结果存储在模块内的机制……我不明白你的意思。您可以将
my_存储
放在模块中。我试图在模块I
中找到一个记录类型为{v:t;pf:pf}
的解决方案。因此,整数v
及其素因子pf
总是存储在一起。这就是我所说的“模块内部”…好吧,我建议{v:t;可变p:pf}
@SoftTimur,看起来你混淆了定义。模块是在struct
和end
之间定义的任何模块。您指的是类型为t
的值。感谢您的解决方案,它将整数对及其素数因子存储在外部。它应该可以工作,但我正在寻找一种将结果存储在模块内的机制……我不明白你的意思。您可以将my_存储
放在模块中。我试图在模块I
中找到一个记录类型为{v:t;pf:pf}
的解决方案。因此,整数v
及其素因子pf
总是存储在一起。这就是我所说的“模块内部”…好吧,我建议{v:t;可变p:pf}
@SoftTimur,看起来你混淆了定义。模块是在struct
和end
之间定义的任何模块。您指的是类型为t
的值。