如何将Ocaml多态变体设为私有

时间:2018-09-04 11:18:29

标签: ocaml polymorphic-variants

我想将我的某些类型切换为使用Ocaml多态变体,以开放递归的方式将其作为因素,同时仍保留我现有的私有非多态类型的执行方式,以及对模式匹配的详尽检查。

我的产品是编译器,因此类型集会通过各种算法进行更改,目前,我必须将所有构造函数都包含在内,这些构造函数应避免出现“断言错误”的情况。

我应该补充一点,我曾经使用多态变体,但又切换回普通的变体,因为类型推断在多态变体中不能很好地发挥作用:错误消息很难阅读,而且比平常的错误推断错误更多,需要在参数上添加更多类型注释,以保持完整性。问题是没有它们,私有构造函数的执行力很强,但是客户端算法的执行力却很弱。

我不太确定是否可以将构造函数的“临时”子集与隐私结合起来。关于它的实用性有什么建议吗?

编辑:简单示例类型:

(* open *)
type 'a x' = [`A | `B of 'a]

(* closed *)
type x = private 'u x' as 'u

(* open extension *)
type 'a y' = ['a x' | `C of 'a] 

(* closed extension *)
type y = private 'u y' as 'u 

let mkA () = `A
let mkB' (a:'a x') = `B a

(* how to do this? *)
let mkB (a:x) = mkB' (a :> 'a x')

使用开放递归,构造函数必须遵循类型的开放/封闭模式。客户端只会看到关闭的版本。这意味着,与我当前的系统中单个构造函数就足够了,我现在需要为每个封闭类型(构造函数所包含的每种类型)提供一个。

即使我能弄清楚如何做到这一点,如果您说6个相互依赖的类型,所有这些都使用开放递归,导致可能的组合呈指数爆炸,这将非常困难,但尚不清楚这是否是一个优势与仅接受运行时检查相比。添加新的构造函数需要大约2个小时,因为每个模式匹配都会因详尽性错误而失败,并且必须修复..即使新的构造函数在该编译阶段没有用。'

1 个答案:

答案 0 :(得分:0)

私有多态变体仅对模块和接口感兴趣。它们在模块中是公用的,但由于接口的原因,它们在外部是专用的。如果您想在模块外部访问公共表示,则必须提供执行该功能的功能:

module M : sig
  (* open *)
  type 'a x' = [`A | `B of 'a]
  (* closed *)
  type x = private 'u x' as 'u
  val f: x -> x x'
end = struct
  type 'a x' = [`A | `B of 'a]
  type x = 'u x' as 'u
  let f a = a
end

另一种实现方法是更改​​您的类型,仅将head构造函数设为私有:

(* open *)
type 'a x' = [`A | `B of 'a]
(* closed *)
type x = 'u x' as 'u
(* private *)
type px = private x
let f (a: px) = (a :> x)