123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517open!ImportmoduletypeBasic_gen=sigtype'attype('a,'b)f_labeled_fnvalbind:'at->('a->'bt,'bt)f_labeled_fnvalreturn:'a->'at(** The following identities ought to hold (for some value of =):
- [return x >>= f = f x]
- [t >>= fun x -> return x = t]
- [(t >>= f) >>= g = t >>= fun x -> (f x >>= g)]
Note: [>>=] is the infix notation for [bind]) *)(** The [map] argument to [Monad.Make] says how to implement the monad's [map] function.
[`Define_using_bind] means to define [map t ~f = bind t ~f:(fun a -> return (f a))].
[`Custom] overrides the default implementation, presumably with something more
efficient.
Some other functions returned by [Monad.Make] are defined in terms of [map], so
passing in a more efficient [map] will improve their efficiency as well. *)valmap:[`Define_using_bind|`Customof'at->('a->'b,'bt)f_labeled_fn]endmoduletypeBasic=Basic_genwithtype('a,'b)f_labeled_fn:=f:'a->'bmoduletypeBasic_local=Basic_genwithtype('a,'b)f_labeled_fn:=f:'a->'bmoduletypeInfix_gen=sigtype'attype('a,'b)fn(** [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(>>=):'at->('a->'bt,'bt)fn(** [t >>| f] is [t >>= (fun a -> return (f a))]. *)val(>>|):'at->('a->'b,'bt)fnendmoduletypeInfix=Infix_genwithtype('a,'b)fn:='a->'bmoduletypeInfix_local=Infix_genwithtype('a,'b)fn:='a->'bmoduletypeSyntax_gen=sig(** Opening a module of this type allows one to use the [%bind] and [%map] syntax
extensions defined by ppx_let, and brings [return] into scope. *)type'attype('a,'b)fntype('a,'b)f_labeled_fnmoduleLet_syntax:sig(** These are convenient to have in scope when programming with a monad: *)valreturn:'a->'atincludeInfix_genwithtype'at:='atandtype('a,'b)fn:=('a,'b)fnmoduleLet_syntax:sigvalreturn:'a->'atvalbind:'at->('a->'bt,'bt)f_labeled_fnvalmap:'at->('a->'b,'bt)f_labeled_fnvalboth:'at->'bt->('a*'b)tmoduleOpen_on_rhs:sigendendendendmoduletypeSyntax=Syntax_genwithtype('a,'b)fn:='a->'bandtype('a,'b)f_labeled_fn:=f:'a->'bmoduletypeSyntax_local=Syntax_genwithtype('a,'b)fn:='a->'bandtype('a,'b)f_labeled_fn:=f:'a->'bmoduletypeS_without_syntax_gen=sigtype'attype('a,'b)fntype('a,'b)f_labeled_fnincludeInfix_genwithtype'at:='atandtype('a,'b)fn:=('a,'b)fnmoduleMonad_infix:Infix_genwithtype'at:='atandtype('a,'b)fn:=('a,'b)fn(** [bind t ~f] = [t >>= f] *)valbind:'at->('a->'bt,'bt)f_labeled_fn(** [return v] returns the (trivial) computation that returns v. *)valreturn:'a->'at(** [map t ~f] is t >>| f. *)valmap:'at->('a->'b,'bt)f_labeled_fn(** [join t] is [t >>= (fun t' -> t')]. *)valjoin:'att->'at(** [ignore_m t] is [map t ~f:(fun _ -> ())]. [ignore_m] used to be called [ignore],
but we decided that was a bad name, because it shadowed the widely used
[Stdlib.ignore]. Some monads still do [let ignore = ignore_m] for historical
reasons. *)valignore_m:'at->unittvalall:'atlist->'alistt(** Like [all], but ensures that every monadic value in the list produces a unit value,
all of which are discarded rather than being collected into a list. *)valall_unit:unittlist->unittendmoduletypeS_without_syntax=S_without_syntax_genwithtype('a,'b)f_labeled_fn:=f:'a->'bandtype('a,'b)fn:='a->'bmoduletypeS_without_syntax_local=S_without_syntax_genwithtype('a,'b)f_labeled_fn:=f:'a->'bandtype('a,'b)fn:='a->'bmoduletypeS=sigtype'atincludeS_without_syntaxwithtype'at:='atincludeSyntaxwithtype'at:='atendmoduletypeS_local=sigtype'atincludeS_without_syntax_localwithtype'at:='atincludeSyntax_localwithtype'at:='atendmoduletypeBasic2_gen=sig(** Multi parameter monad. The second parameter gets unified across all the computation.
This is used to encode monads working on a multi parameter data structure like
([('a,'b) result]). *)type('a,'e)ttype('a,'b)f_labeled_fnvalbind:('a,'e)t->('a->('b,'e)t,('b,'e)t)f_labeled_fnvalmap:[`Define_using_bind|`Customof('a,'e)t->('a->'b,('b,'e)t)f_labeled_fn]valreturn:'a->('a,_)tendmoduletypeBasic2=Basic2_genwithtype('a,'b)f_labeled_fn:=f:'a->'bmoduletypeBasic2_local=Basic2_genwithtype('a,'b)f_labeled_fn:=f:'a->'bmoduletypeInfix2_gen=sig(** Same as {!Infix}, except the monad type has two arguments. The second is always just
passed through. *)type('a,'e)ttype('a,'b)fnval(>>=):('a,'e)t->('a->('b,'e)t,('b,'e)t)fnval(>>|):('a,'e)t->('a->'b,('b,'e)t)fnendmoduletypeInfix2=Infix2_genwithtype('a,'b)fn:='a->'bmoduletypeInfix2_local=Infix2_genwithtype('a,'b)fn:='a->'bmoduletypeSyntax2_gen=sigtype('a,'e)ttype('a,'b)fntype('a,'b)f_labeled_fnmoduleLet_syntax:sigvalreturn:'a->('a,_)tincludeInfix2_genwithtype('a,'e)t:=('a,'e)tandtype('a,'b)fn:=('a,'b)fnmoduleLet_syntax:sigvalreturn:'a->('a,_)tvalbind:('a,'e)t->('a->('b,'e)t,('b,'e)t)f_labeled_fnvalmap:('a,'e)t->('a->'b,('b,'e)t)f_labeled_fnvalboth:('a,'e)t->('b,'e)t->('a*'b,'e)tmoduleOpen_on_rhs:sigendendendendmoduletypeSyntax2=Syntax2_genwithtype('a,'b)fn:='a->'bandtype('a,'b)f_labeled_fn:=f:'a->'bmoduletypeSyntax2_local=Syntax2_genwithtype('a,'b)fn:='a->'bandtype('a,'b)f_labeled_fn:=f:'a->'bmoduletypeS2_gen=sig(** The same as {!S} except the monad type has two arguments. The second is always just
passed through. *)type('a,'e)ttype('a,'b)fntype('a,'b)f_labeled_fnincludeInfix2_genwithtype('a,'e)t:=('a,'e)tandtype('a,'b)fn:=('a,'b)fnincludeSyntax2_genwithtype('a,'e)t:=('a,'e)tandtype('a,'b)fn:=('a,'b)fnandtype('a,'b)f_labeled_fn:=('a,'b)f_labeled_fnmoduleMonad_infix:Infix2_genwithtype('a,'e)t:=('a,'e)tandtype('a,'b)fn:=('a,'b)fnvalbind:('a,'e)t->('a->('b,'e)t,('b,'e)t)f_labeled_fnvalreturn:'a->('a,_)tvalmap:('a,'e)t->('a->'b,('b,'e)t)f_labeled_fnvaljoin:(('a,'e)t,'e)t->('a,'e)tvalignore_m:(_,'e)t->(unit,'e)tvalall:('a,'e)tlist->('alist,'e)tvalall_unit:(unit,'e)tlist->(unit,'e)tendmoduletypeS2=S2_genwithtype('a,'b)fn:='a->'bandtype('a,'b)f_labeled_fn:=f:'a->'bmoduletypeS2_local=S2_genwithtype('a,'b)fn:='a->'bandtype('a,'b)f_labeled_fn:=f:'a->'bmoduletypeBasic3=sig(** Multi parameter monad. The second and third parameters get unified across all the
computation. *)type('a,'d,'e)tvalbind:('a,'d,'e)t->f:('a->('b,'d,'e)t)->('b,'d,'e)tvalmap:[`Define_using_bind|`Customof('a,'d,'e)t->f:('a->'b)->('b,'d,'e)t]valreturn:'a->('a,_,_)tendmoduletypeInfix3=sig(** Same as Infix, except the monad type has three arguments. The second and third are
always just passed through. *)type('a,'d,'e)tval(>>=):('a,'d,'e)t->('a->('b,'d,'e)t)->('b,'d,'e)tval(>>|):('a,'d,'e)t->('a->'b)->('b,'d,'e)tendmoduletypeSyntax3=sigtype('a,'d,'e)tmoduleLet_syntax:sigvalreturn:'a->('a,_,_)tincludeInfix3withtype('a,'d,'e)t:=('a,'d,'e)tmoduleLet_syntax:sigvalreturn:'a->('a,_,_)tvalbind:('a,'d,'e)t->f:('a->('b,'d,'e)t)->('b,'d,'e)tvalmap:('a,'d,'e)t->f:('a->'b)->('b,'d,'e)tvalboth:('a,'d,'e)t->('b,'d,'e)t->('a*'b,'d,'e)tmoduleOpen_on_rhs:sigendendendendmoduletypeS3=sig(** The same as {!S} except the monad type has three arguments. The second
and third are always just passed through. *)type('a,'d,'e)tincludeInfix3withtype('a,'d,'e)t:=('a,'d,'e)tincludeSyntax3withtype('a,'d,'e)t:=('a,'d,'e)tmoduleMonad_infix:Infix3withtype('a,'d,'e)t:=('a,'d,'e)tvalbind:('a,'d,'e)t->f:('a->('b,'d,'e)t)->('b,'d,'e)tvalreturn:'a->('a,_,_)tvalmap:('a,'d,'e)t->f:('a->'b)->('b,'d,'e)tvaljoin:(('a,'d,'e)t,'d,'e)t->('a,'d,'e)tvalignore_m:(_,'d,'e)t->(unit,'d,'e)tvalall:('a,'d,'e)tlist->('alist,'d,'e)tvalall_unit:(unit,'d,'e)tlist->(unit,'d,'e)tendmoduletypeBasic_indexed=sig(** Indexed monad, in the style of Atkey. The second and third parameters are composed
across all computation. To see this more clearly, you can look at the type of bind:
{[
val bind : ('a, 'i, 'j) t -> f:('a -> ('b, 'j, 'k) t) -> ('b, 'i, 'k) t
]}
and isolate some of the type variables to see their individual behaviors:
{[
val bind : 'a -> f:('a -> 'b ) -> 'b
val bind : 'i, 'j -> 'j, 'k -> 'i, 'k
]}
For more information on Atkey-style indexed monads, see:
{v
Parameterised Notions of Computation
Robert Atkey
http://bentnib.org/paramnotions-jfp.pdf
v} *)type('a,'i,'j)tvalbind:('a,'i,'j)t->f:('a->('b,'j,'k)t)->('b,'i,'k)tvalmap:[`Define_using_bind|`Customof('a,'i,'j)t->f:('a->'b)->('b,'i,'j)t]valreturn:'a->('a,'i,'i)tendmoduletypeInfix_indexed=sig(** Same as {!Infix}, except the monad type has three arguments. The second and
third are composed across all computation. *)type('a,'i,'j)tval(>>=):('a,'i,'j)t->('a->('b,'j,'k)t)->('b,'i,'k)tval(>>|):('a,'i,'j)t->('a->'b)->('b,'i,'j)tendmoduletypeSyntax_indexed=sigtype('a,'i,'j)tmoduleLet_syntax:sigvalreturn:'a->('a,'i,'i)tincludeInfix_indexedwithtype('a,'i,'j)t:=('a,'i,'j)tmoduleLet_syntax:sigvalreturn:'a->('a,'i,'i)tvalbind:('a,'i,'j)t->f:('a->('b,'j,'k)t)->('b,'i,'k)tvalmap:('a,'i,'j)t->f:('a->'b)->('b,'i,'j)tvalboth:('a,'i,'j)t->('b,'j,'k)t->('a*'b,'i,'k)tmoduleOpen_on_rhs:sigendendendendmoduletypeS_indexed=sig(** The same as {!S} except the monad type has three arguments. The second and
third are composed across all computation. *)type('a,'i,'j)tincludeInfix_indexedwithtype('a,'i,'j)t:=('a,'i,'j)tincludeSyntax_indexedwithtype('a,'i,'j)t:=('a,'i,'j)tmoduleMonad_infix:Infix_indexedwithtype('a,'i,'j)t:=('a,'i,'j)tvalbind:('a,'i,'j)t->f:('a->('b,'j,'k)t)->('b,'i,'k)tvalreturn:'a->('a,'i,'i)tvalmap:('a,'i,'j)t->f:('a->'b)->('b,'i,'j)tvaljoin:(('a,'j,'k)t,'i,'j)t->('a,'i,'k)tvalignore_m:(_,'i,'j)t->(unit,'i,'j)tvalall:('a,'i,'i)tlist->('alist,'i,'i)tvalall_unit:(unit,'i,'i)tlist->(unit,'i,'i)tendmoduleS_to_S2(X:S):S2withtype('a,'e)t='aX.t=structincludeXtype('a,'e)t='aX.tendmoduleS2_to_S3(X:S2):S3withtype('a,'d,'e)t=('a,'d)X.t=structincludeXtype('a,'d,'e)t=('a,'d)X.tendmoduleS_to_S_indexed(X:S):S_indexedwithtype('a,'i,'j)t='aX.t=structincludeXtype('a,'i,'j)t='aX.tendmoduleS2_to_S(X:S2):Swithtype'at=('a,unit)X.t=structincludeXtype'at=('a,unit)X.tendmoduleS3_to_S2(X:S3):S2withtype('a,'e)t=('a,'e,unit)X.t=structincludeXtype('a,'e)t=('a,'e,unit)X.tendmoduleS_indexed_to_S2(X:S_indexed):S2withtype('a,'e)t=('a,'e,'e)X.t=structincludeXtype('a,'e)t=('a,'e,'e)X.tendmoduletypeMonad=sig(** 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]. *)moduletypeBasic=BasicmoduletypeBasic2=Basic2moduletypeBasic3=Basic3moduletypeBasic_indexed=Basic_indexedmoduletypeBasic_local=Basic_localmoduletypeBasic2_local=Basic2_localmoduletypeInfix=InfixmoduletypeInfix2=Infix2moduletypeInfix3=Infix3moduletypeInfix_indexed=Infix_indexedmoduletypeInfix_local=Infix_localmoduletypeInfix2_local=Infix2_localmoduletypeSyntax=SyntaxmoduletypeSyntax2=Syntax2moduletypeSyntax3=Syntax3moduletypeSyntax_indexed=Syntax_indexedmoduletypeSyntax_local=Syntax_localmoduletypeSyntax2_local=Syntax2_localmoduletypeS_without_syntax=S_without_syntaxmoduletypeS_without_syntax_local=S_without_syntax_localmoduletypeS=SmoduletypeS2=S2moduletypeS3=S3moduletypeS_indexed=S_indexedmoduletypeS_local=S_localmoduletypeS2_local=S2_localmoduleMake(X:Basic):Swithtype'at:='aX.tmoduleMake2(X:Basic2):S2withtype('a,'e)t:=('a,'e)X.tmoduleMake3(X:Basic3):S3withtype('a,'d,'e)t:=('a,'d,'e)X.tmoduleMake_indexed(X:Basic_indexed):S_indexedwithtype('a,'d,'e)t:=('a,'d,'e)X.tmoduleMake_local(X:Basic_local):S_localwithtype'at:='aX.tmoduleMake2_local(X:Basic2_local):S2_localwithtype('a,'e)t:=('a,'e)X.t(** Define a monad through an isomorphism with an existing monad. For example:
{[
type 'a t = { value : 'a }
include Monad.Of_monad (Monad.Ident) (struct
type nonrec 'a t = 'a t
let to_monad { value } = value
let of_monad value = { value }
end)
]} *)moduleOf_monad(Monad:S)(M:sigtype'atvalto_monad:'at->'aMonad.tvalof_monad:'aMonad.t->'atend):Swithtype'at:='aM.tmoduleOf_monad2(Monad:S2)(M:sigtype('a,'b)tvalto_monad:('a,'b)t->('a,'b)Monad.tvalof_monad:('a,'b)Monad.t->('a,'b)tend):S2withtype('a,'b)t:=('a,'b)M.tmoduleOf_monad3(Monad:S3)(M:sigtype('a,'b,'c)tvalto_monad:('a,'b,'c)t->('a,'b,'c)Monad.tvalof_monad:('a,'b,'c)Monad.t->('a,'b,'c)tend):S3withtype('a,'b,'c)t:=('a,'b,'c)M.tmoduleOf_monad_indexed(Monad:S_indexed)(M:sigtype('a,'i,'j)tvalto_monad:('a,'i,'j)t->('a,'i,'j)Monad.tvalof_monad:('a,'i,'j)Monad.t->('a,'i,'j)tend):S_indexedwithtype('a,'i,'j)t:=('a,'i,'j)M.t(** An eager identity monad with functions heavily annotated with
[@inlined] or [@inline hint].
The implementation is manually written, rather than being
constructed by [Monad.Make]. This gives better inlining
guarantees.
*)moduleIdent:S_localwithtype'at='aend