2008-10-19 3 views
3

저는 아주 초보자 인 OCaml 프로그래머입니다. 그래서 이것이 어리석은/명백한 질문이라면 저를 용서해주십시오. 이 많아서을 흡수 할 수 있으며 문서에서이 부분을 놓쳤을 수 있습니다.OCaml의 필드 업데이트를 일반화 할 수 있습니까?

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

이 : 나는 이런 식으로 뭔가를 작성하는을 원하는 때문에

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 

이 중복 버그 나를 시작 :

나는 다음과 같이 시작있어 코드의 기초가 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

NIT :

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

과 함께 생성 된 코드를 참조 식별자로'val'을 chosing name은 혼란스럽고, val은 모듈 타입에서 바인딩으로 사용된다. – Yttrill

+0

충분합니다. 그것을 바꿨습니다. –

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

좋은 솔루션 .. – Yttrill

+0

이것은 대부분의 경우 올바른 해결책입니다. 중요한 경우 나중에 언제든지 코드를 최적화 할 수 있습니다. 그리고 모든 수단을 통해 우리 모두에게 은혜를 베풀고 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 

컴파일과 :

camlp4o Camlp4MacroParser.cmo q.ml 
관련 문제