签名中的SML多态引用

时间:2017-05-24 23:03:57

标签: reference functional-programming polymorphism sml

有没有办法在签名中创建多态引用常量?

此代码编译,但不是我需要的:

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

1 个答案:

答案 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 ;你可以谷歌那个术语来获取更多信息。