SML中为何函子实例Z3不透明性未生效,而Z3'生效?
为什么SML中不透明签名归属
:>在两处表现不同? 先看这段SML代码:
signature BinaryOp = sig type domain val operation: (domain * domain) -> domain end; signature INTEGER = sig val value: int end; functor ModularInt(K: INTEGER) :> BinaryOp = (* I *) struct type domain = int; fun operation (a,b) = (a+b) mod K.value; end; structure Z3 = ModularInt(struct val value=3 end); structure Z3' :> BinaryOp = Z3; (* II *)
运行后会发现:
Z3.domain和int类型兼容,比如val x: Z3.domain = 0可以正常执行,说明Z3不是不透明的。Z3'.domain是抽象类型,无法直接用int赋值,说明Z3'是不透明的。
原因解析
SML中,不透明签名归属:>的生效时机是结构绑定的瞬间,核心区别在于两处:>的作用对象不同:
第I行的
:>作用于functor的返回签名
这里的:>只是约束ModularInt这个functor返回的结构必须符合BinaryOp签名,但并没有对最终生成的Z3结构做类型隐藏。编译器仍然能追踪到Z3.domain的实际实现是int——因为functor的内部代码明确声明了type domain = int,且Z3是直接绑定到functor的输出,没有额外的不透明约束,所以类型等价性被保留。第II行的
:>作用于结构绑定
这里是直接对Z3进行显式的不透明签名归属,将它重新绑定为Z3'。此时编译器会严格按照BinaryOp签名暴露信息,隐藏Z3'的内部类型细节,把Z3'.domain视为抽象类型,不再允许外部直接使用int赋值或依赖其底层实现。
额外说明
如果想让functor生成的结构直接是不透明的,需要在结构绑定的时候也加上:>,比如:
structure Z3 :> BinaryOp = ModularInt(struct val value=3 end);
这样Z3.domain就会变成抽象类型,无法直接用int赋值。
内容的提问来源于stack exchange,提问作者Marco
相关产品推荐
相关产品推荐

