那么'a here是什么意思?
这就像函数的参数多态性(在 Java 中称为泛型),但对于类型。在此代码集中,哪些存储 int 将具有 type int set
、 strings ---string set
等。 'a 位于前面,因为它是常见的 OCaml 语法。在修改后的语法中,类型变量写在类型名之后:likelist int
或set list int
. 有关不同类型多态性的更多信息,我可以向您推荐一本书Types at programming languages
,第五部分:多态性。如果您了解函数的参数多态性,我认为增强您对类型的了解并不难。
隐藏了哪些细节?
在您的 ML 文件中,类型'a set
定义为元素列表。要搜索列表中的某个元素,必须遍历列表并调用(=)
每个元素(这是函数的List.mem
工作方式)。AFAIR 在 OCaml 中,stdlib 集合被实现为平衡树,并且存储在集合中的值应该具有函数compare: t -> t -> int
,其中存储在集合t
中的元素的类型。但是集合可以有不同的定义,如果你只看 .mli 中的抽象类型,那么你只能猜测它是如何在 .ml 文件中实现的。
确实,在这个定义中,类型'a list
已经被用来实现 type ,但是从接口文件中,这个信息是不可见的——隐藏的部分是type 真的是 a'a set
的事实。模块的实现方式,以及对外部世界可用的信息的选择,使得程序可以在不知道它是如何制作的情况下使用该类型。set
list
set
这是软件设计的一个重要特征,因为它让开发人员无需更改使用它的代码即可更改该模块的实现。使类型抽象强制分离:如果您尝试在模块外部使用 alist
作为 a ,您将收到类型错误。set
输入'一个集合='一个列表
AFAIR,这一行引入了一个“类型同义词”(或别名)说:这里和下面的类型set
是相同的list
,你可以使用set
期望的函数,list
反之亦然。
当你看到'a set
你应该明白它只是一组东西,当你把 astring
放到 set 时,它就会是 a string set
。如果你看到'a set
你不能说存储或将存储在这个集合中,但如果你看到string set
,你可以。上面的书中也提到了类型同义词。
附言
所以你的意思是 type 'a set = 'a list 表示该集合期望列表作为参数?
不,它没有。您只需在此行中添加新的类型别名。它不会缩小可以替换为 'a 类型变量的类型的数量。如果你写
# type 'a set = 'a list;;
type 'a set = 'a list
# let create x : _ set = [x];;
val create : 'a -> 'a set = <fun>
进而
List.map ((+)1) (create 2);;
编译器会将 of 的类型推断create 2
为 an int set
(因为类型的参数使用了一个值int
,并且该函数的返回类型是),然后它会查看其类型别名(同义词)表以及何时理解该类型与类型相同,它将继续类型推断的过程。'a
create
'a set
set
list
您应该明白,在创建新同义词时您应该编写正确数量的类型变量,即type 'a new_t = ('a*'b) list
对我和编译器都没有任何意义。左边应该有至少和右边一样多的类型变量: type ('a, 'b) new_t = ('a * 'b) list
例如,有效。