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에 매크로 시스템이 있다고 생각하지 않습니다. 또 무엇을 할 수 있습니까?
해결책
아니, 당신은 평범한 ocaml에서 원하는 것을 할 수 없습니다. 구문 연장을 작성할 수 있습니다 CAMLP4 (아마도 당신이 익숙한 것과는 다른 종류의 매크로 시스템이지만) 변형 될 것입니다.
UPDATE_FIELD x f y
~ 안으로
x.f <- y
또는 물건을 해시 테이블에 넣고 포도 타입 안전에 넣을 수 있습니다.
참고 : OCAML 버전 3.10에 포함 된 CAMLP4 버전은 이전 버전과 다르고 호환되지 않습니다. 최신 버전에 대한 자세한 내용은 참조하십시오 OCAML 튜토리얼 사이트.
다른 팁
원하는 것을 할 수는 없지만 고차 기능으로 보일러 플레이트를 크게 줄일 수 있습니다.
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)이 있으며 일부 작업으로 이런 종류의 일을 구현할 수 있습니다.
위에서 언급 한 바와 같이 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
제휴하지 않습니다 StackOverflow