1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889moduletypeS=Hashtbl_intf.SmoduleMake(H:sigincludeHashable.Svalto_dyn:t->Dyn.tend)=structincludeMoreLabels.Hashtbl.Make(H)let[@ocaml.warning"-32"]add=`Use_setletfind=find_optletfind_exntkey=matchfind_opttkeywith|Somev->v|None->Code_error.raise"Hashtbl.find_exn"[("key",H.to_dynkey)]letsettkeydata=replacet~key~dataletfind_or_addtkey~f=matchfindtkeywith|Somex->x|None->letx=fkeyinsettkeyx;xletfoldit~init~f=foldt~init~f:(fun~key~dataacc->fkeydataacc)letfoldt~init~f=foldit~init~f:(fun_x->fx)letof_listl=leth=create(List.lengthl)inletrecloop=function|[]->Result.Okh|(k,v)::xs->(matchfindhkwith|None->sethkv;loopxs|Somev'->Error(k,v',v))inlooplletof_list_exnl=matchof_listlwith|Result.Okh->h|Error(key,_,_)->Code_error.raise"Hashtbl.of_list_exn duplicate keys"[("key",H.to_dynkey)]letadd_exntkeydata=matchfindtkeywith|None->settkeydata|Some_->Code_error.raise"Hastbl.add_exn: key already exists"[("key",H.to_dynkey)]letaddtkeydata=matchfindtkeywith|None->settkeydata;Result.Ok()|Somep->Result.Errorpletkeyst=foldit~init:[]~f:(funkey_acc->key::acc)letto_dynft=Dyn.Map(foldit~init:[]~f:(funkeydataacc->(H.to_dynkey,fdata)::acc)|>List.sort~compare:(fun(k,_)(k',_)->Dyn.comparekk'))letfilteri_inplacet~f=(* Surely there's a more performant way of writing this. (e.g. using
filter_map_inplace), but starting with a simple thing for now, in part
because [filter_map_inplace] is not available in 4.02. *)letto_delete=ref[]initert~f:(fun~key~data->matchf~key~datawith|false->to_delete:=key::!to_delete|true->());List.iter!to_delete~f:(funk->removetk)letitert~f=itert~f:(fun~key:_~data->fdata)endlethash=MoreLabels.Hashtbl.hash