2017-07-26 7 views
4

私はAST変換によって小さなプログラミング言語を増やしています。つまり、VMから始め、プログラマを助けるレイヤーをゆっくりと追加します。パターンマッチングのOCaml多型バリエーション

各層はその新しいタイプを変換する方法を知っているので、私はこのような何かをやった:

module AST0 = struct 

    type t = [ 
    | `Halt 
    | `In 
    | `Out 
    | `Add of (int * int * int) 
    | `Sub of (int * int * int) 
    ] 

    let lower (ast : t list) = ast 
end 

module AST1 = struct 
    type t = [ 
    AST0.t 

    | `Inc of int 
    | `Dec of int 
    | `Cmp of (int * int * int) 
    ] 

    let lower (ast : t list) = 
    let lower_one = function 
     | `Inc a -> [`Add (a, a, `Imm 1)] 
     | `Dec a -> [`Sub (a, a, `Imm 1)] 
     | `Cmp (a, b) -> [`Sub (13, a, b)] 
     | (x : AST0.t) -> AST0.lower [x]  (* <--- problem line *) 
    in 
    List.concat @@ List.map lower_one ast 
end 

は、残念ながら、私はエラーを取得する:

File "stackoverflow.ml", line 28, characters 8-20: 
Error: This pattern matches values of type AST0.t 
     but a pattern was expected which matches values of type 
     [? `Cmp of 'a * 'b | `Dec of 'c | `Inc of 'd ] 
     The first variant type does not allow tag(s) `Cmp, `Dec, `Inc 

コンパイラはスマートであるので、私は思いました任意のマッチの場合にXYとZのバリアントを処理していないことに気づくのに十分です。のAST1.lowerは実際にはCmpまたはIncまたはDecのいずれかになることはありません。これはそうではないようです。

私はOCamlのタイプシステムを誤解しましたか?私は明白な何かを欠いていますかこれはダムのアプローチですか?

答えて

6

ケースパターンのタイプをローカルに制約することはできません。タイプ制約: AST0.tは、他のパターンのタイプもAST0.tに強制します。そのため、あなたのコードはチェックをタイプしません。 `IncAST0.tに含まれていません。

しかし、OCamlには、あなたがしたいことを正確に示す機能があります。 型制約の代わりに#AST0.tパターンエイリアスを使用します。詳細については、https://caml.inria.fr/pub/docs/manual-ocaml/lablexamples.html#sec46を参照してください。

(* I fixed several other trivial typing problems *) 
    let lower (ast : t list) = 
    let lower_one = function 
     | `Inc a -> [`Add (a, a, 1)] 
     | `Dec a -> [`Sub (a, a, 1)] 
     | `Cmp (a, b, c) -> [`Sub (13, a, b)] 
     | #AST0.t as x -> AST0.lower [x]  (* <--- problem line *) 
    in 
    List.concat @@ List.map lower_one ast 

#AST0.t as xだけでなく(`Halt | `In | `Out | `And _ | `Sub _ as x)の略であるだけでなく、[> AST0.t]から[> AST1.t]から->の右側にあるxの種類を変更します。あなたはそこにAST0.tとしてそれを使うことができます。

+0

これは私のレイヤーを固定しているようですが、別のレイヤーは固定していないようです。私は今それを見ています... – tekknolagi

+0

私が期待していたように、私は何かダムのために他のレイヤーが壊れていました。ご協力ありがとうございました! – tekknolagi

関連する問題