You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: data/tutorials/language/1ms_01_functors.md
+18-20Lines changed: 18 additions & 20 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,67 +3,65 @@ id: functors
3
3
title: Functors
4
4
short_title: Functors
5
5
description: >
6
-
Functors essentially work the same way as functions. The difference is that we are passing modules instead of values.
6
+
In OCaml, a functor is a function at the module-level. Functors take modules as arguments and return a new module.
7
7
category: "Module System"
8
8
---
9
9
10
10
## Introduction
11
11
12
-
In this tutorial, we look at how to use a functor, how to write a functor, and show a couple of use cases involving functors.
12
+
In this tutorial, we look at how to apply functors and how to write functors. We also show some use cases involving functors.
13
13
14
-
As suggested by the name, a _functor_ is almost like a function. However, while functions are between values, functors are between modules. A functor takes a module as a parameter and returns a module as a result. A functor is a parametrised module.
15
-
16
-
In mathematics, [functor](https://en.wikipedia.org/wiki/Functor) means something different. You don't need to know about those functors to understand OCaml's.
14
+
As suggested by the name, a _functor_ is almost like a function. However, while functions are between values, functors are between modules. A functor takes a module as a parameter and returns a module as a result. A functor in OCaml is a parametrised module, not to be confused with a [functor in mathematics](https://en.wikipedia.org/wiki/Functor).
17
15
18
16
**Prerequisites**: [Modules](/docs/modules).
19
17
20
18
## Project Setup
21
19
22
-
This tutorial uses the [Dune](https://dune.build) build tool. Make sure you have installed version 3.7 or later. We start by creating a fresh project. We need a folder named `funkt` with files `dune-project`, `dune`, and `funkt.ml`. The latter two are created empty.
20
+
This tutorial uses the [Dune](https://dune.build) build tool. Make sure you have installed version 3.7 or later. We start by creating a fresh project. We need a folder named `funkt` with files `dune-project`, `dune`, and `funkt.ml`.
21
+
23
22
```shell
24
23
$ mkdir funkt;cd funkt
25
24
```
26
25
27
-
**`dune-project`**
26
+
Place the following in the file **`dune-project`**:
28
27
```lisp
29
28
(lang dune 3.7)
30
29
(package (name funkt))
31
30
```
32
31
33
-
**`dune`**
32
+
The content of the file **`dune`** should be this:
34
33
```lisp
35
34
(executable
36
35
(name funkt)
37
36
(public_name funkt)
38
37
(libraries str))
39
38
```
40
39
41
-
Check this works using the `dune exec funkt` command, it shouldn't do anything (the empty file is valid OCaml syntax) but it shouldn't fail either. The stanza `libraries str` will be used later.
40
+
Create an empty file `funkt.ml`.
41
+
42
+
Check that this works using the `dune exec funkt` command. It shouldn't do anything (the empty file is valid OCaml syntax), but it shouldn't fail either. The stanza `libraries str` makes the `Str` module (which we will use later) available.
42
43
43
44
## Using an Existing Functor: `Set.Make`
44
45
45
-
The standard library contains a [`Set`](/api/Set.html) module providing a data structure that allows set operations like union and intersection. You may check the [Set](/docs/sets) tutorial to learn more about this module, but it is not required to follow the present tutorial. To use the provided type and its associated [functions](/api/Set.S.html), it's necessary to use the functor provided by `Set`. For reference only, here is a shortened version of the interface of `Set`:
46
+
The standard library contains a [`Set`](/api/Set.html) module which is designed to handle sets. This module enables you to perform operations such as union, intersection, and difference on sets. You may check the [Set](/docs/sets) tutorial to learn more about this module, but it is not required to follow the present tutorial.
47
+
48
+
To create a set module for a given element type (which allows you to use the provided type and its associated [functions](/api/Set.S.html)), it's necessary to use the functor `Set.Make` provided by the `Set` module. For reference only, here is a shortened version of the interface of `Set`:
46
49
```ocaml
47
50
module type OrderedType = sig
48
51
type t
49
52
val compare : t -> t -> int
50
53
end
51
54
52
-
module type S = sig
53
-
(** This is the module's signature returned by applying `Make` *)
54
-
end
55
-
56
55
module Make : functor (Ord : OrderedType) -> S
57
56
```
58
57
59
-
Here is how this reads (starting from the bottom-up, then going up):
58
+
Here is how this reads (starting from the bottom, then going up):
60
59
* Like a function (indicated by the arrow `->`), the functor `Set.Make`
61
-
- takes a module having `Set.OrderedType` as signature and
62
-
- returns a module having `Set.S` as signature
63
-
* The module type `Set.S` is the signature of some sort of set
64
-
* The module type `Set.OrderedType` is the signature of elements of a
60
+
- takes a module with signature `Set.OrderedType` and
61
+
- returns a module with signature [`Set.S`](/api/Set.S.html)
62
+
* The module type `Set.OrderedType` requires a type `t` and a function `compare`, which are used to perform the comparisons between elements of the set.
65
63
66
-
**Note**: Most set operation implementations must use a comparison function. Using `Stdlib.compare` would make it impossible to use a user-defined comparison algorithm. Passing the comparison function as a higher-order parameter, as done in `Array.sort`, for example, would add a lot of boilerplate code. Providing set operations as a functor allows specifying the comparison function only once.
64
+
**Note**: Most set operations need to compare elements to check if they are the same. To allow using a user-defined comparison algorithm, the `Set.Make` functor takes a module the specifies both the element type `t` and the `compare` function. Passing the comparison function as a higher-order parameter, as done in `Array.sort`, for example, would add a lot of boilerplate code. Providing set operations as a functor allows specifying the comparison function only once.
0 commit comments