有没有办法在签名中创建多态引用常量?
此代码编译,但不是我需要的:
signature NAME = sig
type 'a name
val empty : 'a name
end
structure Name :> NAME = struct
datatype 'a name = Nil | Val of 'a
val empty = Nil
end
添加所需的参考文献:
signature NAME = sig
type 'a name
val empty : 'a name ref
end
structure Name :> NAME = struct
datatype 'a name = Nil | Val of 'a
val empty = ref Nil
end
产生以下错误:
error: Structure does not match signature.
Signature: val empty: 'a name ref
Structure: val empty: 'a name ref
Reason: Can't match 'a to 'a (Type variable is free in surrounding scope)
Found near struct datatype 'a name = Nil | Val of 'a val empty = ref Nil end
答案 0 :(得分:2)
这实际上与签名无关;如果你写的(在顶层),你会得到同样的问题:
val emptyListRef = ref nil
val emptyIntList = (! emptyListRef) : int list
val emptyStringList = (! emptyListRef) : string list
问题在于emptyListRef
- 或者在您的情况下empty
- 不能是多态的。 (您的编译器声称empty
的类型为'a name ref
,但真正的含义是empty
将具有某种类型的?? name ref
形式,而且还没有弄清楚??
会是什么。)
当您考虑empty
多态时,这种限制是有道理的,那么您就可以编写如下内容:
val () = empty := Val 3
val Val (x : string) = !empty
您可以将empty
设置为int Name
,然后从中读取,就像它持有string Name
一样。没有办法说服编译器相信你不会这样做。
一般规则是,如果右侧采用几种简单形式中的一种,例如构造函数的组合(除了ref
!)和常量以及{{1},则值绑定只允许是多态的。 - 已知是安全的表达式(因为它们不能实现上述不当行为)。此规则称为 value restriction ;你可以谷歌那个术语来获取更多信息。