gpt4 book ai didi

pattern-matching - 模式匹配中的 OCaml 多态变体

转载 作者:行者123 更新时间:2023-12-03 01:12:44 24 4
gpt4 key购买 nike

我正在通过 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 变体,因此它可以告诉 xAST1.lower实际上永远不会成为 Cmp 之一或IncDec 。事实似乎并非如此。

我是否误解了 OCaml 的类型系统?我错过了一些明显的东西吗?这是一种愚蠢的做法吗?

最佳答案

您无法在本地约束案例模式的类型。类型约束 : AST0.t 也将其他模式的类型强制为 AST0.t。这就是为什么你的代码不进行类型检查; `Inc 未包含在 AST0.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) 的缩写,而且还将 -> 右侧的 x 类型从 [> AST1.t] 更改为 [> AST0。 t]。您可以在那里将其用作 AST0.t

关于pattern-matching - 模式匹配中的 OCaml 多态变体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45338950/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com