标准 ML 可以表达数据类型的子类型吗?

Can Standard ML express subtypes of datatypes?

有没有办法在 SML 中有一个 datatype 的子类型,这样子类型将只覆盖 datatype 的一些构造函数?像这样:

(* This works as expected *)
datatype Animal = Cat | Dog | Elephant | Zebra;

(* This overrides the Animal constructors instead of co-opting them *)
datatype Pet = Cat | Dog;

(* This causes a syntax error *)
type Pet = Cat | Dog;

我将添加到@molbdnilo 的回答:你的意思是,可以为多种类型重载 datatype 值构造函数(CatDog 等) ?答案是否定的。这恰好是函数式语言中不常见的特性。一些函数式语言具有某种程度的值重载。

您可以说您的 Pet 类型是 Animal 的子类型,因为值是一个子集,即使 SML 不以这种方式处理子类型。您第三次尝试 type Pet = Cat | Dog 是不可能的,因为 type 用于 别名 不能有自己独特的构造函数,只能引用现有的 类型 而不是 例如 CatDogdatatype 值构造函数存在于值域中,而类型 Pet 和 Animal 存在于类型域中。

所以你可以做的一件事是使用参数化值构造函数:

type lives = int

datatype mammal = Cat of lives | Dog
datatype reptile = Turtle | Lizard
datatype fictive = Unicorn

datatype animal = Mammal of mammal
                | Reptile of reptile
                | Fictive of fictive

现在您的值 Mammal (Cat 9)Reptile TurtleFictive Unicorn 都属于同一类型。我对值构造函数使用大写字母,对类型名称使用小写字母只是为了弄清楚什么是什么,即使在 SML 中并未严格执行此约定。