123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184moduletypeBasic=Monoid_intf.BasicmoduletypeS=Monoid_intf.SmoduleMake(M:Basic)=structincludeMmoduleO=structlet(@)=combineendletreduce=List.fold_left~init:empty~f:combineletmap_reduce~f=List.fold_left~init:empty~f:(funacca->combineacc(fa))endmoduleExists=Make(structtypet=boolletempty=falseletcombine=(||)end)moduleForall=Make(structtypet=boolletempty=trueletcombine=(&&)end)moduleString=Make(structtypet=stringletempty=""letcombine=(^)end)moduleList(M:sigtypetend)=Make(structtypet=M.tlistletempty=[]letcombine=(@)end)moduleAppendable_list(M:sigtypetend)=Make(structtypet=M.tAppendable_list.tletempty=Appendable_list.emptyletcombine=Appendable_list.(@)end)moduleUnit=Make(structincludeUnitletempty=()letcombine()()=()end)moduletypeAdd=sigtypetvalzero:tval(+):t->t->tendmoduleAdd(M:Add)=Make(structincludeMletempty=zeroletcombine=(+)end)moduletypeMul=sigtypetvalone:tval(*):t->t->tendmoduleMul(M:Mul)=Make(structincludeMletempty=oneletcombine=(*)end)moduletypeUnion=sigtypetvalempty:tvalunion:t->t->tendmoduleUnion(M:Union)=Make(structincludeMletcombine=unionend)moduleProduct(A:Basic)(B:Basic)=Make(structtypet=A.t*B.tletempty=A.empty,B.emptyletcombine(a1,b1)(a2,b2)=A.combinea1a2,B.combineb1b2end)moduleProduct3(A:Basic)(B:Basic)(C:Basic)=Make(structtypet=A.t*B.t*C.tletempty=A.empty,B.empty,C.emptyletcombine(a1,b1,c1)(a2,b2,c2)=A.combinea1a2,B.combineb1b2,C.combinec1c2;;end)moduleFunction(A:sigtypetend)(M:Basic)=Make(structtypet=A.t->M.tletempty_=M.emptyletcombinefgx=M.combine(fx)(gx)end)moduleEndofunction=structmoduleLeft(A:sigtypetend)=Make(structtypet=A.t->A.tletemptyx=xletcombinefgx=g(fx)end)moduleRight(A:sigtypetend)=Make(structtypet=A.t->A.tletemptyx=xletcombinefgx=f(gx)end)endmoduleCommutative=struct(* Inject the "proof" of commutativity into a give monoid. *)moduleMake_commutative(M:S)=structincludeMtypecombine_is_commutative=unitendmoduletypeBasic=Monoid_intf.Commutative.BasicmoduletypeS=Monoid_intf.Commutative.SmoduleMake(M:Basic)=Make_commutative(Make(M))moduleExists=Make_commutative(Exists)moduleForall=Make_commutative(Forall)moduleUnit=Make_commutative(Unit)moduleAdd(M:Add)=Make_commutative(Add(M))moduleMul(M:Mul)=Make_commutative(Mul(M))moduleUnion(M:Union)=Make_commutative(Union(M))moduleProduct(A:Basic)(B:Basic)=Make_commutative(Product(A)(B))moduleProduct3(A:Basic)(B:Basic)(C:Basic)=Make_commutative(Product3(A)(B)(C))moduleFunction(A:sigtypetend)(M:Basic)=Make_commutative(Function(A)(M))end