防止SML类型变为eqtype而不隐藏构造函数

时间:2016-07-07 18:51:39

标签: sml

datatype声明中,如果所有变体的所有类型参数都是eqtype s,则标准ML将生成相等类型。

我在一些地方看过评论,哀叹用户无法提供自己的平等定义,并构建自己的方法和SML规则的意外后果(例如裸ref和{{1} s是eqtypes,但array不是eqtype。

来源:http://mlton.org/PolymorphicEquality

  

人们可能希望能够比较两个类型为real的值,因为ref单元格上的指针比较就足够了。不幸的是,类型系统只能表示用户定义的数据类型是否允许相等。

我想知道是否可以阻止 eqtyping。比如说,我正在将一个集合实现为一个二元树(带有一个不必要的变体),我想要保证在结构上比较集合的能力。

datatype Foo = Foo of (real ref)

假设我不希望人们能够将datatype 'a set = EmptySet | SetLeaf of 'a | SetNode of 'a * 'a set * 'a set; SetLeaf(5)SetNode(5, EmptySet, EmptySet)区分开来,因为这是一个破坏抽象的操作。

我尝试使用=的一个简单示例,看看我是否可以使用签名将类型降级为非eqtype。

datatype on = On | Off

似乎透明归属无法阻止(* attempt to hide the "eq"-ness of eqtype *) signature S = sig type on val foo : on end (* opaque transcription to kill eqtypeness *) structure X :> S = struct datatype on = On | Off let foo = On end 成为eqtype,但不透明的归属确实阻止了它。但是,这些解决方案并不理想,因为它们引入了一个新模块并隐藏了数据构造函数。有没有办法阻止自定义类型或类型构造函数成为X.on或允许相等而不隐藏其数据构造函数或引入新模块?

1 个答案:

答案 0 :(得分:6)

简短的回答是否定的。当类型的定义可见时,它的等式是定义所暗示的。阻止它为eq的唯一方法是调整定义,例如,通过添加一个带有real参数的伪构造函数。

顺便说一下,小修正:你的类型foo应该是一个相等的类型。如果您的SML实现不同意,那么它就有错误。当real bar(这是MLton手册讨论的内容)时,另一种情况是datatype 'a bar = Bar of 'a ref。第一个工作但第二个不工作的原因是ref在SML中是神奇的:它具有用户类型不能拥有的多态性等形式。