4

我完全不明白这interface东西在 OCaml 中是如何工作的。

让我们看一个例子:

在此处输入图像描述


关于'a

那么'a here是什么意思?我的意思是我理解在描述功能时,'a意味着arbitrary type. 那么这里的意义是什么呢?这是什么意思arbitrary set

另外,为什么要在前面加上'a set


抽象的

在解释这个例子时,Jason Hickey 的 Objective Caml 简介说:

我们需要定义一个多态类型的集合'a set abstractly。也就是说,在接口中,我们将在不给出定义的情况下声明一个集合类型,防止程序的其他部分知道或依赖于我们选择的集合的特定表示。

从上面的陈述,我猜它的意思是in interface definition, we should hide the implementation details。但隐藏了哪些细节?


输入'一个集合='一个列表

在实现文件中,它说type 'a set = 'a list.

这有什么作用呢?

这是什么意思this set only takes a list?如果确实是这个意思,是否有必要在接口文件中告诉这个,因为这个用户set应该知道它只需要列表,对吗?

4

1 回答 1

9

那么'a here是什么意思?

这就像函数的参数多态性(在 Java 中称为泛型),但对于类型。在此代码集中,哪些存储 int 将具有 type int set、 strings ---string set等。 'a 位于前面,因为它是常见的 OCaml 语法。在修改后的语法中,类型变量写在类型名之后:likelist intset 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的事实。模块的实现方式,以及对外部世界可用的信息的选择,使得程序可以在不知道它是如何制作的情况下使用该类型。setlistset

这是软件设计的一个重要特征,因为它让开发人员无需更改使用它的代码即可更改该模块的实现。使类型抽象强制分离:如果您尝试在模块外部使用 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,并且该函数的返回类型是),然后它会查看其类型别名(同义词)表以及何时理解该类型与类型相同,它将继续类型推断的过程。'acreate'a setsetlist

您应该明白,在创建新同义词时您应该编写正确数量的类型变量,即type 'a new_t = ('a*'b) list对我和编译器都没有任何意义。左边应该有至少和右边一样多的类型变量: type ('a, 'b) new_t = ('a * 'b) list例如,有效。

于 2013-01-09T12:34:52.680 回答