123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168moduletypeS=Set_intf.SmoduleMake(Key:Map_intf.Key)(M:Map_intf.Swithtypekey=Key.t)=structincludeStdlib.MoreLabels.Set.Make(structtypet=Key.tletcomparexy=Ordering.to_int(Key.comparexy)end)type'amap='aM.tletto_list=elementsletto_list_mapt~f=(* optimize if we get a right fold *)foldt~init:[]~f:(funaacc->fa::acc)|>List.rev;;letmemtx=memxtletaddtx=addxtletremovetx=removextletcompareab=Ordering.of_int(compareab)letis_subsett~of_=subsettof_letare_disjointab=not(existsa~f:(memb))letitert~f=itert~fletmapt~f=mapt~fletfoldt~init~f=foldt~init~fletfor_allt~f=for_allt~fletexistst~f=existst~fletfiltert~f=filtert~fletpartitiont~f=partitiont~fletmin_elt=min_elt_optletmax_elt=max_elt_optletchoose=choose_optletsplitxt=splittxletunion_mapl~f=List.fold_left~init:emptyl~f:(funaccx->lets=fxinunionaccs);;letunion_alll=union_mapl~f:Fun.idexceptionFoundofeltletfindt~f=matchitert~f:(fune->iffethenraise_notrace(Founde)else())with|()->None|exceptionFounde->Somee;;letto_dynt=Dyn.Set(to_listt|>List.map~f:Key.to_dyn)letchoose_exnt=matchchoosetwith|Somee->e|None->Code_error.raise"Set.choose_exn"["t",to_dynt];;letof_keys=M.foldi~init:empty~f:(funk_acc->addacck)letto_mapt~f=foldt~init:M.empty~f:(funkacc->M.setacck(fk))letof_list_mapxs~f=(* We don't [fold_left] & [add] over [xs] because [of_list] has a
specialized implementation *)List.mapxs~f|>of_list;;endmoduleOf_map(Key:Map_intf.Key)(Map:Map_intf.Swithtypekey=Key.t)=structtypeelt=Key.ttype'amap='aMap.ttypet=unitMap.tletempty=Map.emptyletis_empty=Map.is_emptyletsingletonx=Map.singletonx()letcardinal=Map.cardinalletequalab=Map.equalab~equal:(fun()()->true)letcompareab=Map.compareab~compare:(fun()()->Eq)letto_list=Map.keysletto_list_mapt~f=(* optimize if we get a right fold *)Map.to_list_mapt~f:(funa()->fa);;letmemtx=Map.memtxletaddtx=Map.settx()letremovetx=Map.removetxexceptionNot_a_subsetletis_subsett~of_=matchMap.mergetof_~f:(fun_keyab->matcha,bwith|Some(),None->raise_notraceNot_a_subset|_->None)with|(_:t)->true|exceptionNot_a_subset->false;;letare_disjointab=not(Map.existsia~f:(funk()->membk))letitert~f=Map.iterit~f:(funk()->fk)letfoldt~init~f=Map.foldit~init~f:(funk()acc->fkacc)letmapt~f=foldt~init:empty~f:(funxacc->addacc(fx))letfor_allt~f=Map.for_allit~f:(funk()->fk)letexistst~f=Map.existsit~f:(funk()->fk)letfiltert~f=Map.filterit~f:(funk()->fk)letpartitiont~f=Map.partitionit~f:(funk()->fk)letmin_eltt=Map.min_bindingt|>Option.map~f:fstletmax_eltt=Map.max_bindingt|>Option.map~f:fstletchooset=Map.chooset|>Option.map~f:fstletsplittx=leta,x,b=Map.splittxina,Option.is_somex,b;;letunionab=Map.unionab~f:(fun_k()()->Some())letdiffab=Map.mergeab~f:(fun_kab->matchbwith|Some()->None|None->a);;letinterab=Map.mergeab~f:(fun_kab->matchawith|Some()->b|None->None);;letunion_mapl~f=List.fold_left~init:emptyl~f:(funaccx->lets=fxinunionaccs);;letunion_alll=union_mapl~f:Fun.idexceptionFoundofeltletfindt~f=matchitert~f:(fune->iffethenraise_notrace(Founde)else())with|()->None|exceptionFounde->Somee;;letto_dynt=Dyn.Set(to_listt|>List.map~f:Key.to_dyn)letchoose_exnt=matchchoosetwith|Somee->e|None->Code_error.raise"Set.choose_exn"["t",to_dynt];;letof_keyst=Map.mapt~f:ignoreletto_mapt~f=Map.mapit~f:(funk()->fk)letof_listl=List.fold_leftl~init:empty~f:addletof_list_mapl~f=List.fold_leftl~init:empty~f:(funaccx->addacc(fx))letto_seqt=Map.to_seqt|>Seq.map~f:fstend