Monadic programming is about computation on values of the form `'a monad`

which support at the minimum two functions:

```
val return : 'a -> 'a monad
val bind : 'a monad -> ('a -> 'b monad) -> 'b monad
```

This kind of computation is heavily used in the Haskell language, but OCaml supports some extensions designed to make the monads use easier. The use of monads is required in some environment (`lwt`

based applications), and be extremly convenient to deal with error handling (see ` option`

and `result`

).

Some monadic types may also have some added functions : `both`

and `map`

and sometimes many more.

Many monad can be defined. We will present in this page the following monads:

`list`

which is associated with monadic functions;`option`

and`result`

which are associated with monadic functions;`lwt`

which defines computations which return values after a while.

Note: this page provides multiple OCaml interactions using `utop`

. The Jane street's `Base`

or `Core`

library is used. This library has some slightly different conventions than `Stdlib`

.

In order to use the list monad, we have to open the `Base`

or `Core`

module from Jane Street.

The first monadic function is the `List.return`

which returns a list with the single element given as an argument to the function:

```
# #require "base";;
# open Base;;
# List.return 42;;
- : int list = [42]
```

The second monadic function is the `List.bind`

. It takes a list and a function, calls the function for each item of the list and returns the concatenation of all the lists returned by the function. It is a synonymous of `List.concat_map`

.

```
# List.bind [1;2;3] ~f:(fun x -> [x; x*10; x*100]) ;;
- : int list = [1; 10; 100; 2; 20; 200; 3; 30; 300]
```

`bind`

can also be written `(>>=)`

:

```
# List.([1;2;3] >>= (fun x -> [x; x*10; x*100]));;
- : int list = [1; 10; 100; 2; 20; 200; 3; 30; 300]
```

This form makes it easier to chain multiple transformations of the list items.

We can also define a `let*`

operator with the same semantic as `bind`

but a different syntax.

```
# let (let*) l f = List.bind l ~f ;;
val ( let* ) : 'a list -> ('a -> 'b list) -> 'b list = <fun>
# let* x = [1; 2; 3] in [x; x*10; x*100] ;;
- : int list = [1; 10; 100; 2; 20; 200; 3; 30; 300]
```

If we want to process two lists, we can use the `both`

function which returns the list of all pairs made by taking an item from the first list and an item from the second list.

```
# List.(Let_syntax.Let_syntax.both [1; 2; 3] [1; 10; 100] >>= fun (a,b) -> return (a*b));;
- : int list = [1; 10; 100; 2; 20; 200; 3; 30; 300]
```

Like with `(let*)`

, we can have an advantage to define a `(and*)`

token (note: we can use two nested `let*`

to provide the `and*`

behavior):

```
# let (let*) l f = List.bind l ~f ;;
val ( let* ) : 'a list -> ('a -> 'b list) -> 'b list = <fun>
# let (and*) l f = List.Let_syntax.Let_syntax.both ;;
val ( and* ) : 'a list -> 'b list -> ('a * 'b) list = <fun>
# let* a=[1; 2; 3] and* b=[1;10;100] in List.return (a*b);;
- : int list = [1; 10; 100; 2; 20; 200; 3; 30; 300]
# let* a=[1; 2; 3] in let* b=[1;10;100] in List.return (a*b);;
- : int list = [1; 10; 100; 2; 20; 200; 3; 30; 300]
```

We can see that the `List.map`

function can be created with `bind`

and `return`

, but the `(>>|)`

operator as a `List.map`

synonymous is also available:

```
# List.([1; 2; 3] >>= fun x -> return (10*x)) ;;
- : int list = [10; 20; 30]
# List.(let* x=[1; 2; 3] in return (10*x)) ;;
- : int list = [10; 20; 30]
# List.([1; 2; 3] >>| fun x -> 10*x) ;;
- : int list = [10; 20; 30]
```

Note: we can open `List.Monad_infix`

which brings `(>>=)`

and `(>>|)`

.

The `option`

monad is similar with the `list`

monad:

```
# #require "base";;
# open Base;;
# Option.return 42;;
- : int option = Base.Option.Some 42
# Option.(Some 42 >>= fun x -> return (x*2));;
- : int option = Base.Option.Some 84
# Option.(Some 42 >>| fun x -> x*2);;
- : int option = Base.Option.Some 84
```

But it can be handy because there are many functions which return an `option`

value and we want to get its embedded `x`

value if it matchs `Some x`

.

Then we can imagine:

```
# let (let*?) opt f = Option.bind opt ~f ;;
# let*? a = Hashtbl.find my_hash my_key in
let*? b = Hashtbl.find my_hash my_key' in
Option.return (a*b) ;;
```

Here, without having to extract explicitly embedded values from the results of both `Hashtbl.find`

functions, we can use them. And the `bind`

operator makes the result equal to `None`

if any of the function returns `None`

.

The `result`

monad has the same behavior as the `option`

monad. The differences are that `Some`

is replaced by `Ok`

and the `None`

value is replaced by an `Error err`

value which carry the error cause.

Using this monad is interesting when using multiple functions which return a `result`

type. This monad dispense to check each return and automatically abort a call sequence when an `Error`

is returned.

The function `Option.to_result`

(`Stdlib`

) or `Result.of_option`

(`Base`

or `Core`

) can also be used to convert an option result to option. Then the following program can be used.

```
# let (let**) opt f = Result.bind opt ~f ;;
# let** a = Result.of_option ~error:"first key not found"
(Hashtbl.find my_hash my_key) in
let** b = Result.of_option ~error:"second key not found"
(Hashtbl.find my_hash my_key') in
Result.return (a*b) ;;
```

This convertion is handy to tag an error with some information. It may be required to mix functions which returns `option`

and `result`

.

Values of type `'a Lwt.t`

represent computations which can take some time (especially when input/output interactions are involved) and returns a result of type `'a`

. Like the `list`

monad from the Jane Street `Base`

or `Core`

module, we have the `return`

, `map`

, `bind`

, and `both`

functions. We have also many functions which return a such computations.

The idea is to build a computation which can involve sequences and concurrent sets of atomic computations and let a scheduler executes all of them. (The lwt scheduler can't create threads, the parallelism is limited to IO queries).

The smaller example of a computation is `Lwt.return`

:

```
# #require "lwt";;
# #require "lwt.unix";;
# Lwt_main.run @@ Lwt.return 42;;
- : int = 42
```

Note: When `utop`

detects a `Lwt.t`

type, it schedules the corresponding computation with `Lwt_lwt.run`

. Then in a `utop`

session, we could also simply type `Lwt.return 42`

. If this behavior can be handy, it can be misleading since the actual type of `Lwt.return 42`

would not be printed.

We can also chain multiple `lwt`

computations with the bind operator (here, reading a line, then printing it):

```
# Lwt.( Lwt_main.run
(Lwt_io.read_line Lwt_io.stdin >>= Lwt_io.write Lwt_io.stdout));;
let's try
let's try- : unit = ()
```

This can be rewritten:

```
# let (let*) = Lwt.bind;;
val ( let* ) : 'a Lwt.t -> ('a -> 'b Lwt.t) -> 'b Lwt.t = <fun>
# Lwt_main.run (let* line = Lwt_io.read_line Lwt_io.stdin in
Lwt_io.write Lwt_io.stdout line);;
let's try
let's try- : unit = ()
```

However, `lwt`

provides some extensions with the `lwt_ppx`

preprocessor and provides a similar syntax:

```
Lwt_main.run (let%lwt line = Lwt_io.read_line Lwt_io.stdin in
Lwt_io.write Lwt_io.stdout line)
```

The principle is the same with the `(let*)`

operator, but ppx extensions are more powerful, and here, `lwt_ppx`

provides also `try%lwt`

, `for%lwt`

, `while%lwt`

, `assert%lwt`

, `match%lwt`

, `if%lwt`

, and `[%lwt raise ...]`

which are shortcuts of `let%lwt`

followed by some OCaml statements. The usage of the `let%lwt`

syntax is also preferred since it provides a better behavior with respect to exception backtraces.

Note: The `lwt_ppx`

preprocessor can't be loaded by `utop`

. We have to compile the program with the following dune stanzas:

```
(libraries lwt lwt.unix)
(preprocess (pps lwt_ppx))
```

The `lwt`

library provides also a `Lwt.both`

function wich permits the concurrent execution of two computations. The scheduling of the two virtual threads depends of explicit (`Lwt.pause ()`

) or implicit (IO waits) pauses. The following program shows how the `lwt`

scheduler can interleave the execution of two threads:

```
Lwt_main.run @@ Lwt.both
begin
let%lwt () = Lwt_io.write Lwt_io.stdout "line #1\n"
and () = Lwt.pause () in
Lwt_io.write Lwt_io.stdout "line #2\n"
end
begin
let%lwt () = Lwt_io.write Lwt_io.stdout "line #3\n"
and () = Lwt.pause () in
Lwt_io.write Lwt_io.stdout "line #4\n"
end
```

It can be possible to create a new monad if the monads provided by the library doesn't fit a need. Here, we will implement a state monad. This monad carries a state which can be read by `get`

and written by `put`

.

With such a monad and the following program,

```
let (r,s) = run 42 @@
let** a = get in
let** () = put (a+1) in
return 12
in Printf.printf "result = %d state = %d\n" r s
```

we would have the result:

`result = 12 state = 43`

Here, `run`

initializes the state and extract the result and the state from the evaluated monads.

Contrary to the `option`

and `list`

monads, the `get`

monad must obtain the state from somewhere. Then the idea is to make `run`

and `bind`

to feed them with a state which will be passed through the sequence of monad. In other words, `get`

is a function. It has an argument which contains the state, and returns a pair with the result and the new state.

With some monads, it can be adequate to hide the actual state and only permits accesses through the functions provided by the monad. A `t`

type is provided to permits this. An abstract type should be declared by a corresponding `.mli`

file.

An implementation of the state monad can be given by:

```
type 'state t = State of 'state
let return x (State s) = (x,State s)
let get (State s) = (s,State s)
let put x (State s) = ((),State x)
let bind f g (State s) =
let (r, State s') = f (State s)
in g r (State s')
let (>>=) = bind
let (let**) = bind
let run x f =
let (r,State state) = f (State x)
in (r,state)
```

We have seen that `lwt`

comes with a preprocessor which defines some operators like `let%lwt`

, `match%lwt`

. We can acheive an analog declarations with the `ppx_let`

preprocessor.

It declare the following token `let%bind`

, `let%map`

, `match%bind`

, `match%map`

, `if%bind`

, `if%map`

, `while%bind`

. They are designed to work with a `open Monad.Let_syntax`

statement where `Monad`

is one of the monad from the Base/Core library from Jane Street.

With this notation, we can write:

```
open Core
let () =
match
let open Option.Let_syntax in
let%bind a = Some 42 in
let%bind b = Some 6 in
return (Printf.printf "%d\n" (a*b))
with
| Some () -> ()
| None -> ()
```

A local `open Option.Let_syntax`

can be handy if the program use different monads.

More information is available here ppx_let page. This includes the convention which must be applied on a custom monad if we want it to be compatible with `ppx_let`

.

A monad can be created easily by defining:

- a type constructor:
`type 'a monad = ...`

- a type converter:
`val return : 'a -> 'a monad`

- a combinator:
`val bind : 'a monad -> ('a -> 'b monad) -> 'b monad`

However, to qualify as a monad, some rules must be verified:

- left identity:
`return x >>= f`

is equivalent to`f x`

- right identity:
`m >>= return`

is equivalent to`m`

- associativity:
`m >>= fun x -> (f x >>= g)`

is equivalent to`(m >>=f) >>= g`

The following characters are supported when defining a `let_`

operator:

`$ & * + - / = > @ ^ | <`

It may be followed by multiple characters from this list:

`$ & * + - / = > @ ^ | < ! ? % :`

OCaml gives you some liberty about the `let_`

operator. The usual bind operator is `(let*)`

, and the map operator is `(let+)`

. The `Lwt.Syntax`

module contains these operators.