Comp
操作にかなりのコストがかかるモジュールを定義しました。ほとんどの場合、 typeComp.t
の値に対して type の値をint
計算でき、これを使用して多くの操作を高速化できます。そこで、x
2 つのケースを表す型を次のように定義します。1) 整数が計算されている 2) そうでない場合
type x = A of (Comp.t, int) | B of Comp.t
a の整数を計算しようとする関数convert: x -> x
が作成されましたComp.t
。この整数が存在しない可能性があります。この関数もコストがかかります。
let convert (v: x): x =
match v with
| A _ -> v
| B c ->
try to calculate the integer "i" from "c",
return "A (c, i)" if the integer is found; otherwise, return "B c".
最初に、比較関数は次のless than
ように記述できます。
open Comp
let lt (x0: x) (x1: x): bool =
let x0, x1 = Comp.convert x0, Comp.convert x1 in
match x0, x1 with
| A (c0, i0), A (c1, i1) ->
i0 < i1 (* which is very fast *)
| A (c0, _), B c1 | B c0, A (c1, _) | B c0, B c1 ->
Comp.lt c0 c1 (* which is quite slow *)
...
let b0 = lt x0_o x1_o in
let b1 = le x0_o x1_o in (* "le" call "convert" too *)
let b2 = ge x0_o x1_o in (* "ge" call "convert" too *)
...
コストがかかり、時々呼び出す可能性のあるconvert
関数以外にも多くの関数があるため(たとえば、)、変換が値に影響を与えるようにしたいと考えています。たとえば、 と の値を変更して、後で関数 (たとえば 、 ) がおそらく既に変換された引数を受け取るようにしたいので、ブロック全体の計算が高速になります。lt
le
ge
lt
x0_o
x1_o
le
ge
変更可能なレコードのようなものを使用する必要があると思いますが、誰かに例を教えてもらえますか? また、一般的に、計算を最適化するためにこれを行う (副作用を許容する) ことは良い考えですか?