ocaml - 多态性变体的打结

标签 ocaml

我在一个模块中定义了一个变体,另一个模块基本上用更多的情况扩展了该变体,因此我使用了多态变体。

为了防止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 情况。

我应该怎么做才能解决这个问题?

我不确定是否应该不声明变体并将其保持打开状态,因为我确实希望从详尽检查中受益。

最佳答案

如果你真的想“稍后再结婚”,这就是你应该有的定义:

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

关于ocaml - 多态性变体的打结,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33801284/

相关文章:

database - 带有 OCaml 的 SQLite

graphics - 如何使用 ocamlopt 的 Graphics 模块编译 ocaml 程序?

list - 整数的Ocaml列表到整数列表的列表(与展平相反)

ocaml - 可变记录字段和 { x with ... }

ocaml - 在多个目录中构建 OCaml 项目

list - Ocaml:使用 list.length

function - Ocaml 99 问题 : can't understand the solution for generating combinations

types - 在插件架构中扩展类型

module - Ocaml破坏性替换错误

f# - 解释模式匹配与切换