123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260open!ImportincludeApplicative_intfmoduleList=List0(** This module serves mostly as a partial check that [S2] and [S] are in sync, but
actually calling it is occasionally useful. *)moduleS_to_S2(X:S):S2withtype('a,'e)t='aX.t=structincludeXtype('a,'e)t='aX.tendmoduleS2_to_S(T:T.T)(X:S2):Swithtype'at=('a,T.t)X.t=structincludeXtype'at=('a,T.t)X.tendmoduleS2_to_S3(X:S2):S3withtype('a,'d,'e)t=('a,'d)X.t=structincludeXtype('a,'d,'e)t=('a,'d)X.tendmoduleS3_to_S2(T:T.T)(X:S3):S2withtype('a,'d)t=('a,'d,T.t)X.t=structincludeXtype('a,'d)t=('a,'d,T.t)X.tendmoduleS3_to_S(T1:T.T)(T2:T.T)(X:S3):Swithtype'at=('a,T1.t,T2.t)X.t=structincludeXtype'at=('a,T1.t,T2.t)X.tendmoduleMake3(X:Basic3):S3withtype('a,'d,'e)t:=('a,'d,'e)X.t=structincludeXlet(<*>)=applyletderived_mapt~f=returnf<*>tletmap=matchX.mapwith|`Define_using_apply->derived_map|`Customx->x;;let(>>|)tf=mapt~fletmap2tatb~f=map~fta<*>tbletmap3tatbtc~f=map~fta<*>tb<*>tcletallts=List.fold_rightts~init:(return[])~f:(map2~f:(funxxs->x::xs))letbothtatb=map2tatb~f:(funab->a,b)let(*>)uv=return(fun()y->y)<*>u<*>vlet(<*)uv=return(funx()->x)<*>u<*>vletall_unitts=List.foldts~init:(return())~f:(*>)moduleApplicative_infix=structlet(<*>)=(<*>)let(*>)=(*>)let(<*)=(<*)let(>>|)=(>>|)endendmoduleMake2(X:Basic2):S2withtype('a,'e)t:=('a,'e)X.t=Make3(structincludeXtype('a,'d,'e)t=('a,'d)X.tend)moduleMake(X:Basic):Swithtype'at:='aX.t=Make2(structincludeXtype('a,'e)t='aX.tend)moduleMake_let_syntax3(X:For_let_syntax3)(Intf:sigmoduletypeSend)(Impl:Intf.S)=structmoduleLet_syntax=structincludeXmoduleLet_syntax=structincludeXmoduleOpen_on_rhs=ImplendendendmoduleMake_let_syntax2(X:For_let_syntax2)(Intf:sigmoduletypeSend)(Impl:Intf.S)=Make_let_syntax3(structincludeXtype('a,'d,_)t=('a,'d)X.tend)(Intf)(Impl)moduleMake_let_syntax(X:For_let_syntax)(Intf:sigmoduletypeSend)(Impl:Intf.S)=Make_let_syntax2(structincludeXtype('a,_)t='aX.tend)(Intf)(Impl)(** This functor closely resembles [Make3], and indeed it could be implemented
much shorter in terms of [Make3]. However, we implement it by hand so that
the resulting functions are more efficient, e.g. using [map2] directly instead of
defining [apply] in terms of it and then [map2] in terms of that. For most
applicatives this does not matter, but for some (such as Bonsai.Value.t), it has a
larger impact. *)moduleMake3_using_map2(X:Basic3_using_map2):S3withtype('a,'d,'e)t:=('a,'d,'e)X.t=structincludeXletapplytfta=map2tfta~f:(funfa->fa)let(<*>)=applyletderived_mapt~f=returnf<*>tletmap=matchX.mapwith|`Define_using_map2->derived_map|`Customx->x;;let(>>|)tf=mapt~fletbothtatb=map2tatb~f:(funab->a,b)letmap3tatbtc~f=map2(map2tatb~f)tc~f:(funfabc->fabc)letallts=List.fold_rightts~init:(return[])~f:(map2~f:(funxxs->x::xs))let(*>)uv=map2uv~f:(fun()y->y)let(<*)uv=map2uv~f:(funx()->x)letall_unitts=List.foldts~init:(return())~f:(*>)moduleApplicative_infix=structlet(<*>)=(<*>)let(*>)=(*>)let(<*)=(<*)let(>>|)=(>>|)endendmoduleMake2_using_map2(X:Basic2_using_map2):S2withtype('a,'e)t:=('a,'e)X.t=Make3_using_map2(structincludeXtype('a,'d,'e)t=('a,'d)X.tend)moduleMake_using_map2(X:Basic_using_map2):Swithtype'at:='aX.t=Make2_using_map2(structincludeXtype('a,'e)t='aX.tend)moduleMake3_using_map2_local(X:Basic3_using_map2_local):S3_localwithtype('a,'d,'e)t:=('a,'d,'e)X.t=structincludeXletapplytfta=map2tfta~f:(funfa->fa)let(<*>)=applyletderived_mapt~f=map2~f:(fun()->f)(return())t[@nontail]letmap=matchX.mapwith|`Define_using_map2->derived_map|`Custommap->map;;let(>>|)tf=mapt~fletbothtatb=map2tatb~f:(funab->a,b)letmap3tatbtc~f=letres=map2(bothtatb)tc~f:(fun(a,b)c->fabc)inres;;letallts=List.fold_rightts~init:(return[])~f:(map2~f:(funxxs->x::xs))let(*>)uv=map2uv~f:(fun()y->y)let(<*)uv=map2uv~f:(funx()->x)letall_unitts=List.foldts~init:(return())~f:(*>)moduleApplicative_infix=structlet(<*>)=(<*>)let(*>)=(*>)let(<*)=(<*)let(>>|)=(>>|)endendmoduleMake2_using_map2_local(X:Basic2_using_map2_local):S2_localwithtype('a,'e)t:=('a,'e)X.t=Make3_using_map2_local(structincludeXtype('a,'d,'e)t=('a,'d)X.tend)moduleMake_using_map2_local(X:Basic_using_map2_local):S_localwithtype'at:='aX.t=Make2_using_map2_local(structincludeXtype('a,'e)t='aX.tend)moduleOf_monad2(M:Monad.S2):S2withtype('a,'e)t:=('a,'e)M.t=Make2(structtype('a,'e)t=('a,'e)M.tletreturn=M.returnletapplymfmx=M.bindmf~f:(funf->M.mapmx~f)letmap=`CustomM.mapend)moduleOf_monad(M:Monad.S):Swithtype'at:='aM.t=Of_monad2(structincludeMtype('a,_)t='aM.tend)moduleCompose(F:S)(G:S):Swithtype'at='aF.tG.t=structtype'at='aF.tG.tincludeMake(structtypenonrec'at='atletreturna=G.return(F.returna)letapplytftx=G.apply(G.map~f:F.applytf)txletcustom_mapt~f=G.map~f:(F.map~f)tletmap=`Customcustom_mapend)endmodulePair(F:S)(G:S):Swithtype'at='aF.t*'aG.t=structtype'at='aF.t*'aG.tincludeMake(structtypenonrec'at='atletreturna=F.returna,G.returnaletapplytftx=F.apply(fsttf)(fsttx),G.apply(sndtf)(sndtx)letcustom_mapt~f=F.map~f(fstt),G.map~f(sndt)letmap=`Customcustom_mapend)end