我正在通過AST變換增長一種小型編程語言。也就是說,從虛擬機開始,慢慢添加一些幫助程序員的層。模式匹配中的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變體,它可以說明x
在AST1.lower
將永遠不會是Cmp
或Inc
或Dec
之一。這似乎並非如此。
我誤解了OCaml的類型系統嗎?我錯過了明顯的東西嗎?這是一種愚蠢的做法嗎?
所以這似乎已經修復了我的一個層,但沒有另一個。我現在正在考慮... – tekknolagi
正如我預料的那樣,另一層因爲我做了一些愚蠢的事情而被打破了。感謝您的幫助! – tekknolagi