OCamlのフィールド更新の記録は一般化できますか?
質問
私は非常に初心者のOCamlプログラマなので、これが愚かで明白な質問である場合はご容赦ください。吸収すべき多くのがあり、ドキュメントではこれを見逃しているかもしれません。
次のようなコードのベースがあります:
let update_x p x =
add_delta p;
p.x <- x;
refresh p
let update_y p y =
add_delta p;
p.y <- y;
refresh p
let update_z p z =
add_delta p;
p.z <- z;
refresh p
このようなことを書きたいので したいので、重複が私を悩ませ始めています:
let update_scalar p scalar value =
add_delta p;
magic_reflection (p, scalar) <- value;
refresh p
この方法でxを更新すると、次のように呼び出すことができます。
update_scalar p 'x' value
これは、「マクロ!」を呼び出します。私にはOCamlにマクロシステムがあるとは思わない。他に何ができますか?
解決
いいえ、あなたは普通のOCamlでは望んでいることをすることはできません。 camlp4 (これはおそらく慣れているものとは異なる種類のマクロシステム)が変換されます
UPDATE_FIELD x f y
into
x.f <- y
別の方法として、ハッシュテーブルにデータを詰め込み、タイプセーフを無視することもできます。
注:OCamlバージョン3.10以降に含まれているcamlp4のバージョンは、以前のバージョンとは異なり、互換性がありません。最新バージョンについては、 OCamlチュートリアルサイトを参照してください。
他のヒント
希望することはできませんが、高階関数を使用して定型文を大幅に削減できます。
let update_gen set p x =
add_delta p;
set p x;
refresh p
let update_x = update_gen (fun p v -> p.x <- v)
let update_y = update_gen (fun p v -> p.y <- v)
let update_z = update_gen (fun p v -> p.z <- v)
OCamlにはマクロシステム(camlp4)があり、この種の機能を実装することができます。いくつかの作業が必要です。
上記のように、ocamlにはマクロシステムがあります。そして、このタスクのために必要なのはほんの一部です:
open Printf
type t = { mutable x : float; mutable y : float; mutable z : float; mutable t : int; }
let add_delta p = p.t <- p.t + 1
let refresh p = printf "%d) %.2f %.2f %.2f\n" p.t p.x p.y p.z
DEFINE UPD(x) = fun p v ->
add_delta p;
p.x <- v;
refresh p
let update_x = UPD(x)
let update_y = UPD(y)
let update_z = UPD(z)
let () =
let p = { x = 0.; y = 0.; z = 0.; t = 0; } in
update_x p 0.1;
update_y p 0.3;
update_z p 2.0
コンパイル:
ocamlfind ocamlc -package camlp4.macro -syntax camlp4o q.ml -o q
生成されたコードを見るには:
camlp4o Camlp4MacroParser.cmo q.ml
所属していません StackOverflow