Skip to content

Commit fd84c78

Browse files
committed
Add MDX in with-test deps
1 parent af57e5f commit fd84c78

File tree

7 files changed

+145
-23
lines changed

7 files changed

+145
-23
lines changed

CREDITS.md

+33-21
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,59 @@
11
# Preface
22

33
Preface is a free (an open-source) library written in (and for)
4-
[OCaml](https://ocaml.org) and released under the [MIT license](LICENSE)
5-
The library is mainly maintained by:
4+
[OCaml](https://ocaml.org) and released under the [MIT
5+
license](LICENSE) The library is mainly maintained by:
66

77
- [Didier Plaindoux](https://github.com/d-plaindoux)
88
- [Pierre Ruyter](https://github.com/gr-im)
99
- [Xavier Van de Woestyne](https://github.com/xvw/)
1010

1111
### Warm thanks and help
1212

13-
- [Gabriel Scherer](https://github.com/gasche) for many design choice and
14-
technical help about specific subject
15-
- [Andrey Mokhov](https://github.com/snowleopard) for his help in understanding
16-
Selectives (and Free Selective) and constant reviews related to Selectives
17-
- [Florian Angeletti](https://github.com/Octachron) for advices and help
13+
- [Gabriel Scherer](https://github.com/gasche) for many design choice
14+
and technical help about specific subject
15+
- [Andrey Mokhov](https://github.com/snowleopard) for his help in
16+
understanding Selectives (and Free Selective) and constant reviews
17+
related to Selectives
18+
- [Florian Angeletti](https://github.com/Octachron) for advices and
19+
help
1820
- [Oleg Kiselyov](http://okmij.org/ftp) for advices about Freer monad
19-
- [XHTMLBoy](https://github.com/xhtmlboi) for providing an implementation of Freer capable of not executing the continuation
20-
- [Pierre-Evariste Dagand](https://pages.lip6.fr/Pierre-Evariste.Dagand/) for a lot of help with Arrows
21+
- [XHTMLBoy](https://github.com/xhtmlboi) for providing an
22+
implementation of Freer capable of discarding the continuation
23+
- [Pierre-Evariste
24+
Dagand](https://pages.lip6.fr/Pierre-Evariste.Dagand/) for a lot of
25+
help with Arrows
2126

2227
## Used libraries
2328

24-
Preface use several libraries (especially for unit tests). For more information,
25-
feel free to refer to the OPAM files located at the root of the project.
26-
Here is a list of our dependancies:
29+
Preface use several libraries (especially for unit tests). For more
30+
information, feel free to refer to the OPAM files located at the root
31+
of the project. Here is a list of our dependancies:
2732

2833
- [Alcotest](https://github.com/mirage/alcotest) - for the definition
2934
of unit tests
30-
- [QCheck](https://github.com/c-cube/qcheck) - for the definition of properties
31-
based testing (coupled with Alcotest)
35+
- [QCheck](https://github.com/c-cube/qcheck) - for the definition of
36+
properties based testing (coupled with Alcotest)
37+
- [Either](https://github.com/mirage/either) - for having an
38+
`Either.t` before OCaml `4.12`
39+
- [mdx](https://github.com/realworldocaml/mdx) - for guide as tests
3240

3341

3442
## Used tools
3543

36-
In addition to [OCaml](https://ocaml.org), we use tools from the OCaml ecosystem:
44+
In addition to [OCaml](https://ocaml.org), we use tools from the OCaml
45+
ecosystem:
3746

38-
- [Dune](https://github.com/ocaml/dune) - as a build system (and task runner)
39-
- [OCamlformat](https://github.com/ocaml-ppx/ocamlformat) - as a code formatter
40-
in order to keep our code formatted according to fixed standards.
41-
- [Odoc](https://github.com/ocaml/odoc) - as a documentation generator.
47+
- [Dune](https://github.com/ocaml/dune) - as a build system (and task
48+
runner)
49+
- [OCamlformat](https://github.com/ocaml-ppx/ocamlformat) - as a code
50+
formatter in order to keep our code formatted according to fixed
51+
standards.
52+
- [Odoc](https://github.com/ocaml/odoc) - as a documentation
53+
generator.
4254

4355
In addition, we use [Merlin](https://github.com/ocaml/merlin) and
44-
[Tuareg](https://github.com/ocaml/tuareg) or
45-
[OCaml mode](https://github.com/ocaml/caml-mode) as IDE. For the more
56+
[Tuareg](https://github.com/ocaml/tuareg) or [OCaml
57+
mode](https://github.com/ocaml/caml-mode) as IDE. For the more
4658
adventurous with more RAM
4759
[IntelliJ](https://plugins.jetbrains.com/plugin/4986-ocaml-support).

dune-project

+2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
(lang dune 2.8)
22
(name preface)
3+
(using mdx 0.1)
4+
(package (name preface))

guides/dune

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
(mdx
2+
(packages preface)
3+
(files *.md))

guides/test.md

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
```ocaml
2+
# #require "preface"
3+
```
4+
5+
# A deep dive into the modular breakdown of Preface
6+
7+
Preface uses a modular cut that can be complex at first glance. In
8+
this guide, we will see how to implement several abstractions, in
9+
several ways, for the `option` type. Preface's design choice are
10+
briefly explained/described [on the
11+
README](https://github.com/xvw/preface#some-design-choices)
12+
13+
## Giving a Functor to our Option
14+
15+
Although cutting is daunting, Preface tries as much as possible to
16+
offer an "easy" approach, which we will call the "*Happy Path*". For
17+
example, let's add a `Functor` for `option`. The most standard
18+
approach to building a Functor is to provide a parameterised type and
19+
a map function. So, we could use the module
20+
`Preface.Make.Functor.Via_map` and give it a module of type:
21+
`Preface.Specs.Functor.WITH_MAP` respecting this interface:
22+
23+
```ocaml
24+
# #show Preface.Specs.Functor.WITH_MAP
25+
module type WITH_MAP = sig type 'a t val map : ('a -> 'b) -> 'a t -> 'b t end
26+
```
27+
28+
Now that we know how to implement a `Functor`, let's do it.
29+
30+
```ocaml
31+
module Opt_functor = Preface.Make.Functor.Via_map (struct
32+
type 'a t = 'a option
33+
let map f = function
34+
| Some x -> Some (f x)
35+
| None -> None
36+
end)
37+
```
38+
39+
Let's see if the whole interface has been implemented:
40+
41+
```ocaml
42+
# #show Opt_functor
43+
module Opt_functor :
44+
sig
45+
type 'a t = 'a option
46+
val map : ('a -> 'b) -> 'a option -> 'b option
47+
val replace : 'a -> 'b option -> 'a option
48+
val void : 'a option -> unit option
49+
module Infix : sig ... end
50+
val ( <$> ) : ('a -> 'b) -> 'a option -> 'b option
51+
val ( <&> ) : 'a option -> ('a -> 'b) -> 'b option
52+
val ( <$ ) : 'a -> 'b option -> 'a option
53+
val ( $> ) : 'a option -> 'b -> 'b option
54+
end
55+
```
56+
57+
Perfect. Now let's try to use our freshly created combinators.
58+
59+
```ocaml
60+
# Opt_functor.(succ <$> Some 10)
61+
- : int option = Some 11
62+
```
63+
64+
For many objects, it is generally not necessary to go further than the
65+
minimum definition. It allows to derive a complete interface by
66+
implementing relatively few functions (just the bare necessities).
67+
68+
## Giving a monad to our option
69+
70+
`Functor` is a special case because it offers only one definition
71+
path. On the other hand, `Monad` is a bit more interesting, as it is
72+
possible to describe a monad in three different ways:
73+
74+
1. Using `return` and `bind`
75+
2. Using `return`, `map` and `join`
76+
3. Using `return`, and the kleisli composition.
77+
78+
For this tutorial, we will see how to build a `Monad` module using the
79+
first two strategies.
80+
81+
### Using Bind
82+
83+
This is generally the most standard way to describe a monad (at least
84+
in the Haskell world). First Let's see what requirements are needed to
85+
build a monad with `bind` (and `return`):
86+
87+
```ocaml
88+
# #show Preface.Specs.Monad.WITH_BIND
89+
module type WITH_BIND =
90+
sig
91+
type 'a t
92+
val return : 'a -> 'a t
93+
val bind : ('a -> 'b t) -> 'a t -> 'b t
94+
end
95+
```
96+
97+
> You may have noticed that the signature is called `WITH_BIND` and
98+
> not `WITH_RETURN_AND_BIND`. This is an internal Preface
99+
> convention. When a function must be provided in all minimal
100+
> definitions, it is mandatory and therefore not repeated in its
101+
> module name.
102+
103+
104+

lib/preface_core/dune

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
(library
22
(name preface_core)
3-
(package preface)
3+
(public_name preface.core)
44
(libraries either))

lib/preface_make/dune

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
(name preface_make)
33
(public_name preface.make)
44
(modules_without_implementation preface_make)
5-
(libraries either preface_core preface.specs))
5+
(libraries either preface.core preface.specs))

preface.opam

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ depends: [
2828
"alcotest" {with-test}
2929
"qcheck-core" {with-test}
3030
"qcheck-alcotest" {with-test}
31+
"mdx" {with-test}
3132
"odoc"{with-doc}
3233
]
3334

0 commit comments

Comments
 (0)