使用 ADT 和(可能)GADT 在类型系统中表达层次结构

Expressing a hierarchy within a type-system with ADT and (possibly) GADT

在我的类型系统中,我想支持可升级类型,其中 Int 如果与除法一起使用,将升级为 Double,而 String 将升级为 StringBuffer 如果与串联一起使用。我可以用 agebraic 数据类型来表达它吗,这样如果编译器试图提升错误的类型,它就会抛出一个类型错误?

例如:

type ty =
  | Int
  | Double
  | String
  | StringBuffer
  | Promotable of ref ty

但是,Int只能提升到Double,不能提升到StringBufferString.

使用 GADT:

type _ ty =
  | Int : arith ty
  | Double : arith ty
  | String : text ty
  | StringBuffer : text ty
  | Promotable of ref ty : ... ??

其中arithtext需要是类型"family"(种类,类型class)?我可以用 OCaml 表达吗?

提前致谢!

编辑:基于以下答案的示例用法:

let promote : type a. a ty -> a ty = function
  | Promotable (Int, IntToDouble) ->Double (* StringBuffer here would not type-check *)
  | Promotable (String, StringToStringBuffer) -> StringBuffer
  | t -> t

您可以有另一个 GADT 来描述层次结构是什么,然后期望当有人试图提升价值时向您提供证明。例如:

type arith
type text

type (_ , _) lessThan =
  | IntToDouble          : (arith, arith) lessThan
  | StringToStringBuffer : (text, text) lessThan

type _ ty =
  | Int          : arith ty
  | Double       : arith ty
  | String       : text ty
  | StringBuffer : text ty
  | Promotable   : 'ref ty * ('ref, 'promo) lessThan -> 'promo ty