@@ -22,26 +22,26 @@ pay attention to the case; you need to type `Set.Make(String)` and not
22
22
` Set.Make(string) ` . The reason behind this is explained in the
23
23
"Technical Details" section at the bottom.
24
24
25
- Doing this in the OCaml's top level will yield a lot of output:
25
+ Doing this in the OCaml's toplevel will yield a lot of output:
26
26
27
27
``` ocamltop
28
28
module SS = Set.Make(String);;
29
29
```
30
30
31
- What happened here is that after assigning your newly created module to the name
32
- ` SS ` , OCaml's top level then displayed the module, which in this case contains
31
+ What happened here is that after assigning your newly- created module to the name
32
+ ` SS ` , OCaml's toplevel displayed the module, which in this case contains
33
33
a large number of convenience functions for working with sets (for example ` is_empty `
34
- for checking if you set is empty, ` add ` to add an element to your set, ` remove ` to
34
+ to check if your set is empty, ` add ` to add an element to your set, ` remove ` to
35
35
remove an element from your set, and so on).
36
36
37
- Note also that this module defines two types: ` type elt = String.t ` representing
38
- the type of the elements, and ` type t = Set.Make(String).t ` representing the type of
39
- the set itself. It's important to note this, because these types are used in the
37
+ Note also that this module defines two types: ` type elt = String.t ` , representing
38
+ the type of the elements, and ` type t = Set.Make(String).t ` , representing the type of
39
+ the set itself. It's important to note this because these types are used in the
40
40
signatures of many of the functions defined in this module.
41
41
42
42
For example, the ` add ` function has the signature ` elt -> t -> t ` , which means
43
43
that it expects an element (a String), and a set of strings, and will return to you
44
- a set of strings. As you gain more experience in OCaml and other function languages,
44
+ a set of strings. As you gain more experience in OCaml and other functional languages,
45
45
the type signature of functions are often the most convenient form of documentation
46
46
on how to use those functions.
47
47
@@ -54,30 +54,30 @@ find what function or value you should use to do this, but this is an excellent
54
54
opportunity to practice reading the type signatures and inferring the answer from them.
55
55
56
56
You want to create a new set (as opposed to modifying an existing set). So you should
57
- look for functions whose return result has type ` t ` (the type representing the set),
57
+ look for functions whose return result has type ` t ` (the type representing the set)
58
58
and which * does not* require a parameter of type ` t ` .
59
59
60
60
Skimming through the list of functions in the module, there's only a handful of functions
61
61
that match that criteria: ` empty: t ` , ` singleton : elt -> t ` , ` of_list : elt list -> t `
62
62
and ` of_seq : elt Seq.t -> t ` .
63
63
64
64
Perhaps you already know how to work with lists and sequences in OCaml or
65
- perhaps you don't. For now, let's assume you don't know, and so we'll focus
65
+ perhaps you don't. For now, let's assume you don't know, so we'll focus
66
66
our attention on the first two functions in that list: ` empty ` and ` singleton ` .
67
67
68
- The type signature for ` empty ` says that it simply returns ` t ` , i.e. an instance
68
+ The type signature for ` empty ` says that it simply returns ` t ` , i.e., an instance
69
69
of our set, without requiring any parameters at all. By intuition, you might
70
70
guess that the only reasonable set that a library function could return when
71
71
given zero parameters is the empty set. And the fact that the function is named
72
72
` empty ` reinforces this theory.
73
73
74
- Is there a way to test this theory? Perhaps if we had a function which
74
+ Is there a way to test this theory? Perhaps if we had a function that
75
75
could print out the size of a set, then we could check if the set we get
76
76
from ` empty ` has a size of zero. In other words, we want a function which
77
- receives a set as a parameter, and returns an integer as a result. Again,
77
+ receives a set as a parameter and returns an integer as a result. Again,
78
78
skimming through the list of functions in the module, we see there is a
79
79
function which matches this signature: ` cardinal : t -> int ` . If you're
80
- not familiar with the word "cardinal", you can look it up on Wikipedia
80
+ not familiar with the word "cardinal," you can look it up on Wikipedia
81
81
and notice that it basically refers to the size of sets, so this reinforces
82
82
the idea that this is exactly the function we want.
83
83
@@ -88,17 +88,17 @@ let s = SS.empty;;
88
88
SS.cardinal s;;
89
89
```
90
90
91
- Excellent, it looks like ` SS.empty ` does indeed create an empty set,
91
+ Excellent! It looks like ` SS.empty ` does indeed create an empty set,
92
92
and ` SS.cardinal ` does indeed print out the size of a set.
93
93
94
94
What about that other function we saw, ` singleton : elt -> t ` ? Again,
95
95
using our intuition, if we provide the function with a single element,
96
96
and the function returns a set, then probably the function will return
97
97
a set containing that element (or else what else would it do with the
98
98
parameter we gave it?). The name of the function is ` singleton ` , and
99
- again if you're unfamiliar with what word, you can look it up on
100
- Wikipedia and see that the word means "a set with exactly one element".
101
- It sounds like we're on the right track again. Let 's test our theory.
99
+ if you're unfamiliar with what word, you can look it up on
100
+ Wikipedia and see that the word means "a set with exactly one element."
101
+ It sounds like we're on the right track, so let 's test our theory.
102
102
103
103
``` ocamltop
104
104
let s = SS.singleton "hello";;
@@ -110,12 +110,12 @@ It looks like we were right again!
110
110
## Working with Sets
111
111
112
112
Now let's say we want to build bigger and more complex sets. Specifically,
113
- let's say we want to add another element to our existing set. So we're
114
- looking for a function with two parameters: One of the parameters should
113
+ let's say we want to add another element to our existing set, so we're
114
+ looking for a function with two parameters. One of the parameters should
115
115
be the element we wish to add, and the other parameter should be the set
116
116
that we're adding to. For the return value, we would expect it to either
117
117
return unit (if the function modifies the set in place), or it returns a
118
- new set representing the result of adding the new element. So we 're
118
+ new set representing the result of adding the new element. We 're
119
119
looking for signatures that look something like ` elt -> t -> unit ` or
120
120
` t -> elt -> unit ` (since we don't know what order the two parameters
121
121
should appear in), or ` elt -> t -> t ` or ` t -> elt -> t ` .
@@ -124,9 +124,9 @@ Skimming through the list, we see 2 functions with matching signatures:
124
124
` add : elt -> t -> t ` and ` remove : elt -> t -> t ` . Based on their names,
125
125
` add ` is probably the function we're looking for. ` remove ` probably removes
126
126
an element from a set, and using our intuition again, it does seem like
127
- the type signature makes sense: To remove an element from a set, you need
127
+ the type signature makes sense. To remove an element from a set, you need
128
128
to tell it what set you want to perform the removal on and what element
129
- you want to remove; and the return result will be the resulting set after
129
+ you want to remove. The return result will be the resulting set after
130
130
the removal.
131
131
132
132
Furthermore, because we see that these functions return ` t ` and not ` unit ` ,
@@ -163,16 +163,16 @@ comparison instead. To do this, we simply have to change the parameter
163
163
that we pass to the ` Set.Make ` function.
164
164
165
165
The ` Set.Make ` function expects a struct with two fields: a type ` t `
166
- that represents the type of the element, and a function ` compare `
166
+ that represents the type of the element and a function ` compare ` ,
167
167
whose signature is ` t -> t -> int ` and essentially returns 0 if two
168
168
values are equal, and non-zero if they are non-equal. It just so happens
169
169
that the ` String ` module matches that structure, which is why we could
170
170
directly pass ` String ` as a parameter to ` Set.Make ` . Incidentally, many
171
171
other modules also have that structure, including ` Int ` and ` Float ` ,
172
- and so they too can be directly passed into ` Set.Make ` to construct a
173
- set of integers, or a set of floating point numbers.
172
+ so they too can be directly passed into ` Set.Make ` to construct a
173
+ set of integers or a set of floating point numbers.
174
174
175
- For our use case, we still want our elements to be of type string, but
175
+ For our use case, we still want our elements to be a string, but
176
176
we want to change the comparison function to ignore the case of the
177
177
strings. We can accomplish this by directly passing in a literal struct
178
178
to the ` Set.Make ` function:
@@ -225,16 +225,16 @@ end);;
225
225
226
226
## Technical Details
227
227
228
- ### Set.Make, types and modules
228
+ ### ` Set.Make ` , Types, and Modules
229
229
230
230
As mentioned in a previous section, the ` Set.Make ` function accepts a structure
231
- with two specific fields, ` t ` and ` compare ` . Modules have structure, and thus
231
+ with two specific fields, ` t ` and ` compare ` . Modules have structure, so
232
232
it's possible (but not guaranteed) for a module to have the structure that
233
- ` Set.Make ` expects. On the other hand, types do not have structure, and so you
233
+ ` Set.Make ` expects. On the other hand, types do not have structure, so you
234
234
can never pass a type to the ` Set.Make ` function. In OCaml, modules start with
235
- an upper case letter and types start with a lower case letter. This is why
235
+ an upper case letter, and types start with a lower case letter. So
236
236
when creating a set of strings, you have to use ` Set.Make(String) ` (passing in
237
- the module named ` String ` ), and not ` Set.Make(string) ` (which would be attempting
237
+ the module named ` String ` ) and not ` Set.Make(string) ` (which would be attempting
238
238
to pass in the type named ` string ` , which will not work).
239
239
240
240
### Purely Functional Data Structures
@@ -247,7 +247,7 @@ that you create are immutable. The functions like `add` and `remove` do not
247
247
actually modify the set you pass in, but instead return a new set representing
248
248
the results of having performed the corresponding operation.
249
249
250
- ### Full API documentation
250
+ ### Full API Documentation
251
251
252
252
This tutorial focused on teaching how to quickly find a function that does what
253
253
you want by looking at the type signature. This is often the quickest and most
0 commit comments