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
的值。