123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293open!ImportmoduletypeKey=sigtypet[@@deriving_inlinecompare,sexp_of]includesig[@@@ocaml.warning"-32"]valcompare:t->t->intvalsexp_of_t:t->Ppx_sexp_conv_lib.Sexp.tend[@@ocaml.doc"@inline"][@@@end](** Values returned by [hash] must be non-negative. An exception will be raised in the
case that [hash] returns a negative value. *)valhash:t->intendmoduleHashable=structtype'at={hash:'a->int;compare:'a->'a->int;sexp_of_t:'a->Sexp.t;}(** This function is sound but not complete, meaning that if it returns [true] then it's
safe to use the two interchangeably. If it's [false], you have no guarantees. For
example:
{[
> utop
open Core;;
let equal (a : 'a Hashtbl_intf.Hashable.t) b =
phys_equal a b
|| (phys_equal a.hash b.hash
&& phys_equal a.compare b.compare
&& phys_equal a.sexp_of_t b.sexp_of_t)
;;
let a = Hashtbl_intf.Hashable.{ hash; compare; sexp_of_t = Int.sexp_of_t };;
let b = Hashtbl_intf.Hashable.{ hash; compare; sexp_of_t = Int.sexp_of_t };;
equal a b;; (* false?! *)
]}
*)letequalab=phys_equalab||(phys_equala.hashb.hash&&phys_equala.compareb.compare&&phys_equala.sexp_of_tb.sexp_of_t);;lethash_param=Caml.Hashtbl.hash_paramlethash=Caml.Hashtbl.hashletpoly={hash;compare=Poly.compare;sexp_of_t=(fun_->Sexp.Atom"_");}letof_key(typea)(moduleKey:Keywithtypet=a)={hash=Key.hash;compare=Key.compare;sexp_of_t=Key.sexp_of_t;};;letto_key(typea){hash;compare;sexp_of_t}=(modulestructtypet=alethash=hashletcompare=compareletsexp_of_t=sexp_of_tend:Keywithtypet=a);;endincludeHashablemoduletypeHashable=sigtype'at='aHashable.t={hash:'a->int;compare:'a->'a->int;sexp_of_t:'a->Sexp.t;}valequal:'at->'at->boolvalpoly:'atvalof_key:(moduleKeywithtypet='a)->'atvalto_key:'at->(moduleKeywithtypet='a)valhash_param:int->int->'a->intvalhash:'a->intend