我是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有一个宏系统。我还能做什么?
答案 0 :(得分:5)
你无法做到你想要的,但你可以通过更高阶的功能大大减少样板:
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),它确实允许你实现这类工作,但有些工作。
答案 1 :(得分:1)
不,你不能在普通的OCaml中做你想做的事。您可以使用camlp4编写一个语法扩展(这是一种宏系统,虽然这种方式与您可能习惯的类型不同)会转换
UPDATE_FIELD x f y
到
x.f <- y
或者,您可以将内容填充到哈希表中并放弃类型安全。
注意:OCaml 3.10及更高版本中包含的camlp4版本与先前版本不同且不兼容。有关最新版本的信息,请参阅the OCaml tutorial site。
答案 2 :(得分:0)
如上所述,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