2008-10-19 57 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 
相關問題