我完全不明白interface
在OCaml中是如何工作的。
让我们看一个例子:
那么'这里的含义是什么?我的意思是我理解在描述函数时,'a
表示arbitrary type
。那么它的含义是什么?这是arbitrary set
吗?
此外,为什么要在set
前面加上'?
在解释此示例时,Jason Hickey's Introduction to Objective Caml说:
我们需要定义一组多态类型的集合抽象。那 是,在界面中我们将声明一个类型'一组而不给出一个 定义,阻止程序的其他部分知道,或 取决于我们选择的集合的特定表示。
从上述陈述中,我猜这意味着in interface definition, we should hide the implementation details
。但隐藏了哪些细节?
在实施文件中,它显示type 'a set = 'a list
。
这是做什么用的?
是否意味着this set only takes a list
?如果它确实意味着这一点,那么是否有必要在界面文件中说明这一点,因为这个set
的用户应该知道它只需要列表,对吗?
答案 0 :(得分:9)
那么'这里的意思是什么?
这就像函数的参数多态(在Java中它被称为泛型),但对于类型。在此代码集中,哪个商店的int将具有类型int set
,字符串--- string set
等等'a'在前面,因为它是常见的OCaml语法。在修订后的语法中,变量是在类型名后写的:如list int
或set list int
。有关不同类型的多态性的更多信息,我可以向您推荐一本书Types at programming languages
,第五部分:多态性。如果您了解函数的参数多态,我认为增强您对类型的知识并不困难。
隐藏了哪些细节?
在ML文件中,类型'a set
被定义为元素列表。要搜索列表中的某个元素,必须遍历列表并为每个元素调用(=)
(这是函数List.mem
的工作方式)。 OCaml中的AFAIR stdlib集实现为平衡树,存储在集合中的值应具有函数compare: t -> t -> int
,其中t
是存储在集合中的元素类型。
但是,可以不同地定义集合,如果仅查看.mli中的抽象类型,那么您只能猜测它是如何在.ml文件中实现的。
实际上,在此定义中,类型'a list
已用于实现类型'a set
,但是从接口文件中,此信息不可见 - 隐藏的部分是set
{1}}类型实际上是list
。模块的实现方式以及选择哪些信息可供外部世界使用,使程序可以使用set
类型而不知道它是如何制作的。
这是软件设计的一个重要特性,因为它让开发人员可以更改该模块的实现,而无需更改使用它的代码。使类型抽象强制执行该分离:如果您尝试在模块外部使用list
作为set
,则会出现类型错误。
输入'a set ='列表
AFAIR,此行引入了“类型同义词”(或别名),说明:类型set
的此处和下方与list
相同,您可以将set
与期待list
,反之亦然。
当您看到'a set
时,您应该了解它只是一组内容,当您设置string
时,它将是string set
。如果您看到'a set
,则无法说出已存储或将存储在此集中的内容,但如果您看到string set
,则可以。上面的书中也提到了类型同义词。
P.S。
所以你的意思是输入'a set ='一个列表表明该集合期待列表作为参数?
不,它没有。您只需在此行中添加新类型别名即可。它不会缩小许多可以替换为'类型变量的类型。如果你写
# 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);;
编译器会将create 2
的类型推断为int set
(因为int
值用于'a
的{{1}}类型的参数,并且该函数的返回类型为create
),然后它将查看其类型别名(同义词)的表,以及何时理解类型'a set
与类型set
相同它将继续进行类型推断过程。
您应该了解在创建新同义词时应该编写正确数量的类型变量,即list
对我和编译器都没有任何意义。左边应该至少有与右边一样多的类型变量:type 'a new_t = ('a*'b) list
,例如,有效。