有没有办法在签名中制作多态引用常量?
这段代码可以编译,但不是我需要的:
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
最佳答案
这实际上与签名无关;如果您(在顶层)编写,您会遇到同样的问题:
val emptyListRef = ref nil
val emptyIntList = (! emptyListRef) : int list
val emptyStringList = (! emptyListRef) : string list
问题是 emptyListRef
- 或者在您的情况下 empty
- 不能是多态的。 (您的编译器声称 empty
具有类型 'a name ref
,但它真正的意思是 empty
将具有 ?? name ref
形式的某种类型,并且尚未弄清楚 ??
是什么。)
当您考虑到如果空
是多态时,这个限制是有意义的,那么您就可以编写如下内容:
val () = empty := Val 3
val Val (x : string) = !empty
其中您设置empty
来保存int Name
,然后从中读取,就像它保存string Name
一样。无法说服编译器相信您不会这样做。
一般规则是,只有当右侧采用几种简单形式之一时,值绑定(bind)才允许是多态的,例如构造函数的组合(除了ref
!)和常量以及fn
- 表达式,已知是安全的(因为它们不能启用上述不当行为)。该规则称为 value restriction ;您可以通过 Google 搜索该术语来获取更多信息。
关于reference - 签名中的 SML 多态引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44169816/