W3cubDocs

/OCaml
Previous Up

8.23 Binding operators

(Introduced in 4.08.0)

Users can define let operators:

   let ( let* ) o f = match o with | None -> None | Some x -> f x let return x = Some x val ( let* ) : 'a option -> ('a -> 'b option) -> 'b option = <fun> val return : 'a -> 'a option = <fun> 

and then apply them using this convenient syntax:

   let find_and_sum tbl k1 k2 = let* x1 = Hashtbl.find_opt tbl k1 in let* x2 = Hashtbl.find_opt tbl k2 in return (x1 + x2) val find_and_sum : ('a, int) Hashtbl.t -> 'a -> 'a -> int option = <fun> 

which is equivalent to this expanded form:

   let find_and_sum tbl k1 k2 = ( let* ) (Hashtbl.find_opt tbl k1) (fun x1 -> ( let* ) (Hashtbl.find_opt tbl k2) (fun x2 -> return (x1 + x2))) val find_and_sum : ('a, int) Hashtbl.t -> 'a -> 'a -> int option = <fun> 

Users can also define and operators:

   module ZipSeq = struct type 'a t = 'a Seq.t open Seq let rec return x = fun () -> Cons(x, return x) let rec prod a b = fun () -> match a (), b () with | Nil, _ | _, Nil -> Nil | Cons(x, a), Cons(y, b) -> Cons((x, y), prod a b) let ( let+ ) f s = map s f let ( and+ ) a b = prod a b end module ZipSeq : sig type 'a t = 'a Seq.t val return : 'a -> 'a Seq.t val prod : 'a Seq.t -> 'b Seq.t -> ('a * 'b) Seq.t val ( let+ ) : 'a Seq.t -> ('a -> 'b) -> 'b Seq.t val ( and+ ) : 'a Seq.t -> 'b Seq.t -> ('a * 'b) Seq.t end 

to support the syntax:

   open ZipSeq let sum3 z1 z2 z3 = let+ x1 = z1 and+ x2 = z2 and+ x3 = z3 in x1 + x2 + x3 val sum3 : int Seq.t -> int Seq.t -> int Seq.t -> int Seq.t = <fun> 

which is equivalent to this expanded form:

   open ZipSeq let sum3 z1 z2 z3 = ( let+ ) (( and+ ) (( and+ ) z1 z2) z3) (fun ((x1, x2), x3) -> x1 + x2 + x3) val sum3 : int Seq.t -> int Seq.t -> int Seq.t -> int Seq.t = <fun> 

8.23.1 Rationale

This extension is intended to provide a convenient syntax for working with monads and applicatives.

An applicative should provide a module implementing the following interface:

   module type Applicative_syntax = sig type 'a t val ( let+ ) : 'a t -> ('a -> 'b) -> 'b t val ( and+ ): 'a t -> 'b t -> ('a * 'b) t end 

where (let+) is bound to the map operation and (and+) is bound to the monoidal product operation.

A monad should provide a module implementing the following interface:

   module type Monad_syntax = sig include Applicative_syntax val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t val ( and* ): 'a t -> 'b t -> ('a * 'b) t end 

where (let*) is bound to the bind operation, and (and*) is also bound to the monoidal product operation.


Previous Up