Pregunta

Soy un programador de OCaml muy novato, así que perdóneme si esta es una pregunta estúpida / obvia. Hay mucho para absorber y es posible que me haya perdido esto en la documentación.

Tengo una base de código que comienza a tener este aspecto:

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 

La duplicación está empezando a molestarme porque quiero escribir algo como esto:

let update_scalar p scalar value =
    add_delta p;
    magic_reflection (p, scalar) <- value;
    refresh p

De esta forma, cuando actualizo x, simplemente puedo llamar:

update_scalar p 'x' value

Esto llama a " macros! " Para mí, pero no creo que OCaml tenga un sistema macro. ¿Qué más puedo hacer?

¿Fue útil?

Solución

No, no puedes hacer lo que quieres en OCaml simple. Puedes escribir una extensión de sintaxis con camlp4 (que es una clase de un sistema macro, aunque es un tipo diferente del que probablemente esté acostumbrado a) que se transformaría

UPDATE_FIELD x f y

en

x.f <- y

Alternativamente, puedes meter cosas en una tabla hash y renunciar a la seguridad de tipos.

NOTA: La versión de camlp4 incluida en OCaml versión 3.10 y posteriores es diferente e incompatible con la versión anterior. Para obtener información sobre la última versión, consulte el sitio de tutoriales de OCaml .

Otros consejos

No puede hacer exactamente lo que quiere, pero puede reducir enormemente la repetición con una función de orden superior:

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 tiene un sistema macro (camlp4) y le permite implementar este tipo de cosas, con algo de trabajo.

Como se indicó anteriormente, ocaml tiene un sistema macro. Y para esta tarea solo se necesita una pequeña fracción:

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

Compilar con:

ocamlfind ocamlc -package camlp4.macro -syntax camlp4o q.ml -o q

Ver el código generado con:

camlp4o Camlp4MacroParser.cmo q.ml
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top