Pergunta

Eu sou um novato muito OCaml programador então por favor me perdoe se esta é uma pergunta estúpida / óbvio. Há muito para absorver e eu possa ter perdido este na documentação.

Eu tenho uma base de código que está começando a olhar como este:

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 

A duplicação está começando a me incomodar porque eu deseja para escrever algo como isto:

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

Desta forma, quando eu atualizar x posso simplesmente chamar:

update_scalar p 'x' value

Esta chama "macros!" para mim, mas eu não acredito que OCaml tem um sistema de macro. O que mais eu posso fazer?

Foi útil?

Solução

Não, você não pode fazer o que quiser em OCaml simples. Você poderia escrever uma extensão de sintaxe com camlp4 (que é uma espécie de um sistema de macro, embora de um tipo diferente do que você provavelmente está acostumado a) que transformaria

UPDATE_FIELD x f y

para

x.f <- y

Como alternativa, você poderia colocar as coisas em uma tabela hash e renunciar segurança de tipo.

NOTA: A versão do camlp4 incluído no OCaml versão 3.10 e posterior é diferente e incompatível com a versão anterior. Para obter informações sobre a versão mais recente, consulte o site OCaml tutorial .

Outras dicas

Você não pode fazer exatamente o que você quiser, mas você pode reduzir muito o clichê com uma função de ordem 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 tem um sistema de macro (camlp4) e ele permite-lhe implementar esse tipo de coisa, com algum trabalho.

Como observado acima ocaml tem sistema de macro. E para esta tarefa é necessária apenas uma pequena fração dela:

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 com:

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

Veja o código gerado com:

camlp4o Camlp4MacroParser.cmo q.ml
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top