Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file hack_monad.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198moduletypeBasic=sigtype'atvalbind:'at->('a->'bt)->'btvalreturn:'a->'at(* 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 (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->f:('a->'b)->'bt)]endmoduletypeInfix=sigtype'at(** [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(** [t >>| f] is [t >>= (fun a -> return (f a))]. *)val(>>|):'at->('a->'b)->'btendmoduletypeS=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. *)includeInfixmoduleMonad_infix:Infixwithtype'at:='at(** [bind t f] = [t >>= f] *)valbind:'at->('a->'bt)->'bt(** [return v] returns the (trivial) computation that returns v. *)valreturn:'a->'at(** [map t ~f] is t >>| f. *)valmap:'at->f:('a->'b)->'bt(** [join t] is [t >>= (fun t' -> t')]. *)valjoin:'att->'at(** [ignore t] = map t ~f:(fun _ -> ()). *)valignore:'at->unittvalall:'atlist->'alisttvalall_ignore:unittlist->unittendmoduleMake(M:Basic):Swithtype'at:='aM.t=structletbind=M.bindletreturn=M.returnletmap_via_bindma~f=M.bindma(funa->M.return(fa))letmap=matchM.mapwith|`Define_using_bind->map_via_bind|`Customx->xmoduleMonad_infix=structlet(>>=)=bindlet(>>|)tf=mapt~fendincludeMonad_infixletjoint=t>>=funt'->t'letignoret=mapt~f:(fun_->())letall=letrecloopvs=function|[]->return(List.revvs)|t::ts->t>>=funv->loop(v::vs)tsinfunts->loop[]tsletrecall_ignore=function|[]->return()|t::ts->t>>=fun()->all_ignoretsend(**
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)]).
*)moduletypeBasic2=sigtype('a,'d)tvalbind:('a,'d)t->('a->('b,'d)t)->('b,'d)tvalmap:[`Define_using_bind|`Customof(('a,'d)t->f:('a->'b)->('b,'d)t)]valreturn:'a->('a,_)tend(** Same as Infix, except the monad type has two arguments. The second is always just
passed through. *)moduletypeInfix2=sigtype('a,'d)tval(>>=):('a,'d)t->('a->('b,'d)t)->('b,'d)tval(>>|):('a,'d)t->('a->'b)->('b,'d)tend(** The same as S except the monad type has two arguments. The second is always just
passed through. *)moduletypeS2=sigincludeInfix2moduleMonad_infix:Infix2withtype('a,'d)t:=('a,'d)tvalbind:('a,'d)t->('a->('b,'d)t)->('b,'d)tvalreturn:'a->('a,_)tvalmap:('a,'d)t->f:('a->'b)->('b,'d)tvaljoin:(('a,'d)t,'d)t->('a,'d)tvalignore:(_,'d)t->(unit,'d)tvalall:('a,'d)tlist->('alist,'d)tvalall_ignore:(unit,'d)tlist->(unit,'d)tendmoduleCheck_S2_refines_S(X:S):(S2withtype('a,'d)t='aX.t)=structtype('a,'d)t='aX.tincludestructopenXlet(>>=)=(>>=)let(>>|)=(>>|)letbind=bindletreturn=returnletmap=mapletjoin=joinletignore=ignoreletall=allletall_ignore=all_ignoreendmoduleMonad_infix=structopenX.Monad_infixlet(>>=)=(>>=)let(>>|)=(>>|)endendmoduleMake2(M:Basic2):S2withtype('a,'d)t:=('a,'d)M.t=structletbind=M.bindletreturn=M.returnletmap_via_bindma~f=M.bindma(funa->M.return(fa))letmap=matchM.mapwith|`Define_using_bind->map_via_bind|`Customx->xmoduleMonad_infix=structlet(>>=)=bindlet(>>|)tf=mapt~fendincludeMonad_infixletjoint=t>>=funt'->t'letignoret=mapt~f:(fun_->())letall=letrecloopvs=function|[]->return(List.revvs)|t::ts->t>>=funv->loop(v::vs)tsinfunts->loop[]tsletrecall_ignore=function|[]->return()|t::ts->t>>=fun()->all_ignoretsend