“接口定义”中`abstract`的含义是什么? [英] What is the meaning of `abstract` in the `interface definition`?

查看:121
本文介绍了“接口定义”中`abstract`的含义是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我完全不理解接口在OCaml中的工作方式。



让我们来看一个例子:








关于'a



所以'a在这里?我的意思是,我明白当描述函数时,'a 表示任意类型。那么这里的含义是什么?它是否意味着任意设置?



另外,为什么要放在<$ c $前面c> set
$ b




摘要



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


我们需要定义一个多态类型的集合 abstractly
是在接口中,我们将声明一个类型'一个集合,而不给出
定义,防止程序的其他部分知道,或
取决于集合的特定表示已经选择了。

从上面的语句中,我猜它意味着在接口定义中,我们应该隐藏实现细节。但隐藏了哪些详细信息?
$ b h2>

在实现文件中,它表示键入'a set ='列表



然后是什么?

是否意味着这个集合只需要一个列表?如果确实如此,那么是否有必要在接口文件中说明这一点,因为 set 的用户应该知道它只需要列表,对吗?

解决方案


那么'a here?'的含义是什么?


这就像函数的参数多态性(在Java中称为泛型),但是对于类型。在此代码集中,哪些商店ints将具有类型 int set ,字符串--- 字符串集等。因为它是常见的OCaml语法。在修订后的语法中,类型变量之后写入类型变量:如 list int set list int 。有关不同种类的多态性的更多信息,我可以向您推荐一本书编程语言类型,第五部分:多态性。如果您了解函数的参数多态性,我认为增加您对类型的知识并不困难。


隐藏了哪些细节?


在你的ML文件中,类型'一个集合被定义为一个列表的元素。要搜索列表中的某个元素,必须迭代列表并为每个元素调用(=)(这是函数 List的方式。 mem 的作品)。在OCaml中的AFAIR,stdlib集合被实现为平衡树,并且存储在集合中的值应该具有函数 compare:t - > t - > int 其中 t 是存储在集合中的元素的类型。
但是可以定义不同的集合,如果您仅查看.mli中的抽象类型,那么您只能猜测它是如何在.ml文件中实现的。



的确,在这个定义中,类型'一个列表已被用于实现类型'一个集合,但是从接口文件中,这些信息是不可见的 - 隐藏的部分是 set 类型真的是 list 。模块的实现方式以及选择向外部世界提供哪些信息使程序可以在不知道如何使用 set 类型的情况下使用<它是制造的。

这是软件设计的一个重要特性,因为它允许开发人员更改该模块的实现,而无需更改使用该模块的代码。使类型抽象实施分离:如果您尝试使用列表作为集合,那么您将得到一个类型错误。


键入'a set ='列表


AFAIR,这一行引入了一个'type synonym'(或别名):在这里和下面的类型 set 与<$ c $相同c> list ,并且可以使用 set 来使用期望 list 的函数,反之亦然。

当您看到'set 时,您应该明白它只是一组东西, string 来设置,那么它将是一个字符串集合。如果您看到'set ,那么您不能说存储或将存储在此集合中的内容,但是如果您看到 string set ,你可以。在上面的书中也提到了类型同义词。






所以你的意思是输入'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 set ),那么它将查看其类型别名表(同义词),以及何时它将理解类型 set 与类型 list

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


I quite don't understand how the interface thing works in OCaml.

Let's see an example:


About the 'a

So what the meaning of 'a here? I mean I understand that when describing the functions, 'a means arbitrary type. Then what's its meaning here? Does it mean arbitrary set?

Also, Why put 'a in front of set?


abstract

When explaining this example, Jason Hickey's Introduction to Objective Caml says:

we need to define a polymorphic type of sets ’a set abstractly. That is, in the interface we will declare a type ’a set without giving a definition, preventing other parts of the program from knowing, or depending on, the particular representation of sets we have chosen.

From the above statements, I guess it means in interface definition, we should hide the implementation details. But what details has been hidden?


type 'a set = 'a list

In the implementation file, it says type 'a set = 'a list.

What does this do then?

Does it mean this set only takes a list? If it does mean this, will it be necessary to tell this in the interface file, since user of this set should know it takes only list, right?

解决方案

So what the meaning of 'a here?

This is like parametric polymorphism for functions (in Java it is known as generics) but for types. In this code sets which store ints will have type int set, strings --- string set etc. 'a is in front because it is common OCaml syntax. In revised syntax type variables are written after typenames: like list int or set list int. For more information about different kinds of polymorphism I can recommend you a book Types at programming languages, part V: Polymorphism. If you understand parametric polymorphism for functions I think it will not be difficult to enhance your knowledge for types.

what details has been hidden?

In your ML file, the type 'a set is defined as a list of elements. To search some element in a list, one must iterate through the list and call (=) for every element (this is the way the function List.mem works). AFAIR in OCaml the stdlib sets are implemented as balanced trees and values which are stored in sets should have function compare: t -> t -> int where t is the type of elements stored in the set. However sets can be defined differently and if you look only at abstract types in .mli, then you can only guess how it is implemented in .ml file.

Indeed, in this definition, the type 'a list has been used to implement the type 'a set, but from the interface file, this information is not visible - the hidden part is the fact that the set type is really a list. The way the module has been implemented, and the choice of which information has been made available to the external world, make it possible for a program to use the set type without knowing how it's made.

It's an important feature of software design, since it let the developer change the implementation of that module without having to change the code that uses it. Making the type abstract enforces that separation: you will get a type error if you try to use a list as a set outside the module.

type 'a set = 'a list

AFAIR, this line introduces a 'type synonym' (or alias) saying: here and below the type set is the same as list and you can use set with functions which expect list and vice versa.

When you see 'a set you should understand that it is just a set of something, when you put a string to set then it will be a string set. If you see 'a set you can't say what is stored or will be stored in this set, but if you see string set, you can. Type synonyms are also mentioned in the book above.

P.S.

So you mean type 'a set = 'a list indicates that the set is expecting list as parameters?

No, it doesn't. You just add new type alias in this line. It doesn't shrink a number of types which can be substituted to 'a type variable. If you write

# type 'a set = 'a list;;
type 'a set = 'a list
# let create x : _ set = [x];;
val create : 'a -> 'a set = <fun>

and then

List.map ((+)1) (create 2);;

the compiler will infer the type of create 2 as an int set (since an int value is used for the parameter of type 'a of create, and the return type of that function is 'a set), then it will look at its table of type aliases (synonyms) and when it will understand that type set is the same as type list it will continue the type inference's process.

You should understand that you should write the right number of type variables when creating a new synonym, i.e. type 'a new_t = ('a*'b) list doesn't make any sense both for me and the compiler. There should be at least as many type variables in the left as in the right: type ('a, 'b) new_t = ('a * 'b) list, for example, works.

这篇关于“接口定义”中`abstract`的含义是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆