从参数上将`Null构造函数添加到多态变体

时间:2019-04-02 13:17:59

标签: ocaml

以下类型声明不起作用:

type 'a or_null = [ 'a | `Null ]

type 'a or_null = [ 'a | `Null ] constraint 'a = [> `A | `B ]

显示消息:

  

错误:类型'a不能扩展为多态变体类型

     

提示:您是说'a

我想在内存表示(和语法)中不使用另一层的情况下实现此目的。特别是,我想避免使用诸如

这样的选项类型
type 'a or_null = | A of 'a | Null

有没有办法仅使用多态变体来拥有这种类型?最终目标是写例如'a or_null类型的单子。 (这实际上是棘手的部分。)

1 个答案:

答案 0 :(得分:3)

多态变体无法跟踪缺少特定构造函数的情况。这意味着我们不能真正编写通常的绑定。如果我们尝试

 let bind x f =
   match x with 
   | `Null -> `Null
   | x -> f x

我们得到

 val bind: ([> `Null] as 'a) -> ('a -> ([>`Null] as 'b)) -> 'b

如果出于可读性考虑,我们添加以下类型缩写

 type 'a m = [> `Null] as 'a

(这是or_null的替代定义)以前的类型读为

val bind: 'a m -> ('a m -> 'b m) -> 'b m

换句话说,f的函数参数bind必须已经自行处理了`Null的情况,因为类型系统无法在其中表达约束x <> `Null比赛的第二个分支。