【发布时间】:2017-07-26 23:21:37
【问题描述】:
我正在通过 AST 转换开发一种小型编程语言。也就是从VM开始,慢慢添加对程序员有帮助的层。
由于每一层都知道如何转换它的新类型,我做了这样的事情:
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
我认为,由于编译器足够聪明,可以注意到我没有在任意匹配情况下处理 X Y 和 Z 变体,因此它可以判断 AST1.lower 中的 x 实际上永远不会是 Cmp 或Inc 或 Dec。好像不是这样的。
我是否误解了 OCaml 的类型系统?我错过了一些明显的东西吗?这是一种愚蠢的方法吗?
【问题讨论】:
标签: pattern-matching ocaml abstract-syntax-tree