4

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

Let's see an example:

enter image description here


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?

Jackson Tale
  • 25,428
  • 34
  • 149
  • 271

1 Answers1

9

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.

didierc
  • 14,572
  • 3
  • 32
  • 52
Kakadu
  • 2,837
  • 19
  • 29
  • `u can use set with functions which expect list and vice versa`. I quite don't understand this. So you mean `type 'a set = 'a list` indicates that the `set` is expecting `list` as parameters? – Jackson Tale Jan 09 '13 at 13:06
  • Thanks. I am a newbie. do you mind telling me what the part of **: _ set** means in **let create x : _ set = [x];;**? – Jackson Tale Jan 09 '13 at 13:41
  • This is wild card. Usually it is useful in pattern-matching or in type expressions (like here). `_ list` means that it is list of something and inference of this type `something` I leave to the compiler. You can try to explain difference between `'a list` and `_ list` as a simple exercise because don't want to explain it now :) – Kakadu Jan 09 '13 at 13:59
  • `In this code sets which store ints will have type int set, strings --- string set etc.`. So `'a set` means this set can store arbitrary type. But what if I am writing a `map`? it takes two parameters (key and value), should I write `'a 'a map`? – Jackson Tale Jan 09 '13 at 21:08
  • @JacksonTale You'd write `'a 'b map` or maybe `'k 'v map` or `'key 'value map` for readbility - the types have to have different names - otherwise you couldn't unambiguously refer to them on the right side of the definition. – sepp2k Jan 09 '13 at 21:12
  • @sepp2k so you mean `type 'a set`'s `'a` should depend on the number of parameters? I mean I still can't figure out how to write `type ... interface_name` for arbitrary interface files. In C, we don't define parameters for interface level, we define for each method inside. What's the concept in OCaml?? – Jackson Tale Jan 09 '13 at 21:19
  • @sepp2k, what if I define a interface file `myInterface` which is not a storage? and it has two functions, one takes an int and a float, the other takes a string? should I write `type int float string myInterface`? – Jackson Tale Jan 09 '13 at 21:22
  • @JacksonTale I'm not sure what you mean about C there. C doesn't have parametrized types. I also don't know what you mean by "'a should depend on the number of parameters". In the example `'a` is the name of `set`'s one and only type parameter. Its name doesn't depend on anything. Instead of `'a` you could also name it `'element_type` or `'foobar`. Type parameters are the same as function parameters in that regard: Their names are arbitrary, but different parameters to the same function can't have the same name. – sepp2k Jan 09 '13 at 21:23
  • @JacksonTale If your interface only contains functions and no types, it shouldn't contain the `type` keyword at all. – sepp2k Jan 09 '13 at 21:23
  • @sepp2k thanks for your reply. My real question is `when I should what`. `When should I use type 'a 'b interface`, `When should I use type 'k, 'v, 'u interface` etc. Does 'type of interface' mean 'What are the possible types inside the interface`? – Jackson Tale Jan 09 '13 at 21:40
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/22484/discussion-between-sepp2k-and-jackson-tale) – sepp2k Jan 09 '13 at 21:40