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