A ppx writer that generates hash functions from type expressions and definitions.
Type definitions: [@@deriving hash]
Expressions: [%hash_fold: TYPE]
and [%hash: TYPE]
Types, record fields: [@hash.ignore]
type t = {
s : string;
x : (int * bool) list;
}
[@@deriving hash]
This will generate a function hash_fold_t : Hash.state -> t -> Hash.state
.
Where Hash
is Ppx_hash_lib.Std.Hash
.
The generated function follows the structure of the type; allowing user overrides at every
level. This is in contrast to ocaml's builtin polymorphic hashing Hashtbl.hash
which
ignores user overrides.
Also generated is a direct hash-function hash : t -> Hash.hash_value
. This function will be named hash_<T>
when != "t".
The direct hash function is the one suitable for Hashable.Make
.
In a module signature, type t [@@deriving hash]
will add both hash_fold_t
and hash
(or hash_<T>
) to the signature.
A folding hash function is accessed/created as [%hash_fold: TYPE]
.
A direct hash function is accessed/created as [%hash: TYPE]
.
Types can be annotated with [@hash.ignore]
so that they are not
incorporated into the computed hash value.
type second_only = (string [@hash.ignore]) * int [@@deriving hash]
Mutable records fields must have such an annotation.
type t = {
mutable s : string [@hash.ignore];
x : (int * bool) list;
}
[@@deriving hash]
The annotation [@compare.ignore]
(and [@ignore]
) implies
[@hash.ignore]
, in order to preserve the invariant that compare x y = 0
implies hash x = hash y
.
So long as all types in support hashing, the following common pattern:
module T = struct
type t = <TYPE-EXP> [@@deriving compare, sexp]
let hash = Hashtbl.hash
end
include T
include Hashable.Make (T)
Can this be written as:
module T = struct
type t = <TYPE-EXP> [@@deriving compare, hash, sexp]
end
include T
include Hashable.Make (T)
ppx/ppx_hash/doc/design.notes
ppx/ppx_hash/runtime-lib/make_std.ml