2008-10-19 43 views
3

我是一个非常新手的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有一个宏观系统。我还可以做些什么?

回答

1

不,你不能在简单的OCaml中做你想做的事情。你可以写一个camlp4语法扩展(这是一种宏观系统,虽然不同种类的比你可能习惯了),这将改变

UPDATE_FIELD x f y 

x.f <- y 

另外,你可以把东西填入散列表中,并放弃类型安全。

注意:OCaml版本3.10及更高版本中包含的camlp4版本与之前的版本不同且不兼容。有关最新版本的信息,请参阅the OCaml tutorial site

+0

尼特:艇员选拔`val`作为标识符名称令人困惑,'val'被用作模块类型的绑定。 – Yttrill 2011-01-22 14:41:29

+0

够公平的。改变了它。 – 2011-01-22 20:17:28

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)和它允许你实施这种事情,做一些工作。

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 
相关问题