私は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のタイプシステムを誤解しましたか?私は明白な何かを欠いていますかこれはダムのアプローチですか?
これは私のレイヤーを固定しているようですが、別のレイヤーは固定していないようです。私は今それを見ています... – tekknolagi
私が期待していたように、私は何かダムのために他のレイヤーが壊れていました。ご協力ありがとうございました! – tekknolagi