与多态变体打结
Knot-tying with polymorphic variants
我在一个模块中定义了一个变体,另一个模块基本上用更多案例扩展了该变体,所以我使用的是多态变体。
为了防止Extended.exp
中的子表达式成为Core.exp
中的子表达式,这个结稍后打结。
module Core = struct
type 'a expr_f = [
| `Int of int
| `Plus of 'a expr_f * 'a expr_f
]
type expr = expr expr_f
end
module Ex = struct
type 'a expr_f = [
| 'a Core.expr_f
| `Times of 'a expr_f * 'a expr_f
]
type expr = expr expr_f
end
这似乎行得通,直到我们使用递归函数遍历Ex.expr
.
类型的值
let rec test : Ex.expr -> Ex.expr = function
| `Int i -> `Int i
| `Plus (a, b) -> `Plus (test a, test b)
| `Times (a, b) -> `Times (test a, test b)
我收到一个类型错误,因为 Expr.expr_f
的类型是:
type 'a expr_f = [
| `Int of int
| `Plus of 'a Core.expr_f * 'a Core.expr_f
| `Times of 'a expr_f * 'a expr_f
]
子表达式使用 Core.expr_f
,不支持额外的 Times
大小写。
我应该怎么做才能解决这个问题?
我不确定是否应该不声明该变体并将其保持打开状态,因为我确实想从详尽检查中受益。
如果你真的想要"tie the knot later",这是你应该有的定义:
module Core = struct
type 'a expr_f = [
| `Int of int
| `Plus of 'a * 'a
]
type expr = expr expr_f
end
module Ex = struct
type 'a expr_f = [
| 'a Core.expr_f
| `Times of 'a * 'a
]
type expr = expr expr_f
end
我在一个模块中定义了一个变体,另一个模块基本上用更多案例扩展了该变体,所以我使用的是多态变体。
为了防止Extended.exp
中的子表达式成为Core.exp
中的子表达式,这个结稍后打结。
module Core = struct
type 'a expr_f = [
| `Int of int
| `Plus of 'a expr_f * 'a expr_f
]
type expr = expr expr_f
end
module Ex = struct
type 'a expr_f = [
| 'a Core.expr_f
| `Times of 'a expr_f * 'a expr_f
]
type expr = expr expr_f
end
这似乎行得通,直到我们使用递归函数遍历Ex.expr
.
let rec test : Ex.expr -> Ex.expr = function
| `Int i -> `Int i
| `Plus (a, b) -> `Plus (test a, test b)
| `Times (a, b) -> `Times (test a, test b)
我收到一个类型错误,因为 Expr.expr_f
的类型是:
type 'a expr_f = [
| `Int of int
| `Plus of 'a Core.expr_f * 'a Core.expr_f
| `Times of 'a expr_f * 'a expr_f
]
子表达式使用 Core.expr_f
,不支持额外的 Times
大小写。
我应该怎么做才能解决这个问题?
我不确定是否应该不声明该变体并将其保持打开状态,因为我确实想从详尽检查中受益。
如果你真的想要"tie the knot later",这是你应该有的定义:
module Core = struct
type 'a expr_f = [
| `Int of int
| `Plus of 'a * 'a
]
type expr = expr expr_f
end
module Ex = struct
type 'a expr_f = [
| 'a Core.expr_f
| `Times of 'a * 'a
]
type expr = expr expr_f
end