2017-03-24 1 views
1

OCaml을 처음 사용하고 있으며, 큰 OCaml 프로젝트로 건너 뛰려고합니다. 다른 유형을 구성하는 유형을 추적하는 동안 이러한 유형을 어떻게 사용할지 생각하려고 했으므로 크기가 큰 프로젝트에서 사용하는 방법에 매우 가깝다고 생각되는 작은 예제로 분해했습니다.OCaml 중첩 형식을 사용하여 변수 바인딩하기

나는 세 개의 필드로 만든 레코드 유형 expression있는 경우 : 지금은 원하는 경우

let exp_const = {e_id=10; 
       e_node= Const 10; 
       e_loc={x=10; y=10}} 

다음 e_node 필드가 정수이면 나는이 유형의 변수를 바인딩 할 수 있습니다

type expression = {e_id:int; e_node:exp_node; e_loc:location} 
and exp_node = 
    | Const of int 
    | Lval of lval 
    | SizeofStr of string 
and lval = 
    | Var of varinfo 
    | Mem of expression 
and location = {x:int; y:int} 
and varinfo = {vname:string; vorigname:string} 

을 그 e_node 필드는 레코드 타입 인 Lval 타입의 것 lval 나는 그것을하는 방법을 이해할 수 없다. 나는 시도했다 :

let exp_lval_var = 
    {e_id=11; 
    e_node= {vname="int_val"; vorigname="int_val1"}; 
    e_loc={x=10; y=20}} 

그러나 그것은 This expression has type varinfo but an expression was expected of type exp_node를 말한다. 그러나 당신이 유형을 따라 간다면, 그것은!?

여기에 유형을 정확하게 정의하지 않습니까? 아니면 형식을 올바르게 사용하지 않습니까? 나는 OCaml 타입을 사용하는 더 복잡한 예를 실제로 발견 할 수 없었다. 여기에 어떤 제안을 주시면 감사하겠습니다.

답변

1

Const 10 (정확히 10과 반대)을 작성한 것처럼 e_node 필드에 올바른 종류의 값을 얻으려면 Lval (Var { ... })을 작성해야합니다.

let exp_lval_var = 
    {e_id=11; 
    e_node= Lval (Var {vname="int_val"; vorigname="int_val1"}); 
    e_loc={x=10; y=20}} 

첫번째 예 형태를 따르
  • 10

    int
  • Const 10 번째 예

      종류별 exp_node

    이다 형인

  • {vname="int_val"; vorigname="int_val1"}은 그냥 OCaml의에서 문서에 대한 레이블하지 exp_node

값 생성자 Const, VarLval 같은 유형 인 유형 lval

  • Lval (Var {vname="int_val"; vorigname="int_val1"})이다 유형 varinfo
  • Var {vname="int_val"; vorigname="int_val1"}이다. 형식의 값을 만들기 위해 식의 일부로 나타나야합니다.

  • +0

    감사합니다! 그럴 경우 많은 의미가 있습니다. – Jesse

    +0

    그래서'exp_lval_var'을 사용하면 그것에 관련된'vname'에 액세스하고 싶습니다. 그걸 잡아낼 기능이 있어야할까요? 예를 들어'Printf.printf "% s"에 대한 인수에서와 같이 장소에서'vname' 레코드 요소를 잡기 위해 타입을 가로 지르는 일을하는 것은 매우 Ocaml 관용적이지 않습니다. (부작용이 실제로 부작용이 아니기 때문에 부작용이 없다는 것을 알고 있습니다.) – Jesse

    +0

    이와 같은 기능이 최선의 방법일까요? let get_vname {e_id = _; e_node = 노드; e_loc = _} = 노드를 과 일치 시키십시오. Const i -> Printf.sprintf "e_node는 int입니다 : % i (vname 없음)"i | Lval lv -> (lv와 | Var {vname = vstring; vorigname = vostring} -> Printf.sprintf "% s에서 % s"로 vstring vstring | Mem _ -> "표현 있음") | SizeofStr sizestr -> Printf.sprintf "e_node is SizeofStr : % s (no vname)"sizestr 그럼'Printf.printf "% s"(get_vname exp_lval_var) ;; ' – Jesse