`module type Basic = `sig .. end``
`type `'a `t`
`val bind : `'a t -> ('a -> 'b t) -> 'b t``
`val return : `'a -> 'a t``
`val map : `'a t -> f:('a -> 'b) -> 'b t``
Although `map` can be defined in terms of `bind` and `return`, it is almost always better to define it directly. We require it in `Basic`, which is the argument to the `Make` functor, to encourage direct definition.

For situations where defining `map` in terms of `bind` is fine, you can do:

``        let map t ~f = Monad.map_via_bind t ~f ~return ~bind``
`module type Infix = `sig .. end``
`type `'a `t`
`val (>>=) : `'a t -> ('a -> 'b t) -> 'b t``
`t >>= f` returns a computation that sequences the computations represented by two monad elements. The resulting computation first does `t` to yield a value `v`, and then runs the computation returned by `f v`.
`val (>>|) : `'a t -> ('a -> 'b) -> 'b t``
`t >>| f` is `t >>= (fun a -> return (f a))`.
```val map_via_bind : ```'a 'b 'c 'd.
'c ->
f:('a -> 'b) -> return:('b -> 'd) -> bind:('c -> ('a -> 'd) -> 'd) -> 'd``````
`module type S = `sig .. end``
`include `Infix``
A monad is an abstraction of the concept of sequencing of computations. A value of type 'a monad represents a computation that returns a value of type 'a.
`module Monad_infix : `Infix with type t := 'a t``
`val bind : `'a t -> ('a -> 'b t) -> 'b t``
`bind t f` = `t >>= f`
`val return : `'a -> 'a t``
`return v` returns the (trivial) computation that returns v.
`val map : `'a t -> f:('a -> 'b) -> 'b t``
`map t ~f` is t >>| f.
`val join : `'a t t -> 'a t``
`join t` is `t >>= (fun t' -> t')`.
`val ignore : `'a t -> unit t``
`ignore t` = map t ~f:(fun _ -> ()).
`val all : `'a t list -> 'a list t``
`val all_ignore : `unit t list -> unit t``
`module Make : `functor (M : Basic) -> S with type t := 'a M.t``
`module type Basic2 = `sig .. end``
Multi parameter monad. The second parameter get unified across all the computation. This is used to encode monads working on a multi parameter data structure like (`('a,'b result)`).
`type `('a, 'd) `t`
`val bind : `('a, 'd) t -> ('a -> ('b, 'd) t) -> ('b, 'd) t``
`val map : `('a, 'd) t -> f:('a -> 'b) -> ('b, 'd) t``
`val return : `'a -> ('a, 'b) t``
`module type Infix2 = `sig .. end``
Same as Infix, except the monad type has two arguments. The second is always just passed through.
`type `('a, 'd) `t`
`val (>>=) : `('a, 'd) t -> ('a -> ('b, 'd) t) -> ('b, 'd) t``
`val (>>|) : `('a, 'd) t -> ('a -> 'b) -> ('b, 'd) t``
`module type S2 = `sig .. end``
The same as S except the monad type has two arguments. The second is always just passed through.
`include `Infix2``
`module Monad_infix : `Infix2 with type t := ('a, 'd) t``
`val bind : `('a, 'd) t -> ('a -> ('b, 'd) t) -> ('b, 'd) t``
`val return : `'a -> ('a, 'b) t``
`val map : `('a, 'd) t -> f:('a -> 'b) -> ('b, 'd) t``
`val join : `(('a, 'd) t, 'd) t -> ('a, 'd) t``
`val ignore : `('a, 'd) t -> (unit, 'd) t``
`val all : `('a, 'd) t list -> ('a list, 'd) t``
`val all_ignore : `(unit, 'd) t list -> (unit, 'd) t``
`module Check_S2_refines_S : `functor (X : S) -> S2 with type t = 'a X.t``
`module Make2 : `functor (M : Basic2) -> S2 with type t := ('a, 'd) M.t``