1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
|
type a = [ `A ] [@@deriving hash]
type ab =
[ `A
| `B
]
[@@deriving hash]
type abc_v1 =
[ ab
| `C
]
[@@deriving hash]
type abc_v2 =
[ `A
| `B
| `C
]
[@@deriving hash]
(* Check that the same polymorphic variant has the same hash regardless of which
type it's in. This property is relied on internally to implement hashing of types like
[abc_v1] (see above).
We could potentially use this property to justify support of open polymorphic
variants in the future. *)
let%expect_test "`A hashes the same regardless of which type it's in" =
let h1 = [%hash: a] `A in
let h2 = [%hash: ab] `A in
let h3 = [%hash: abc_v1] `A in
let h4 = [%hash: abc_v2] `A in
let h5 = [%hash: [ ab | `C ]] `A in
assert (h1 = h2);
assert (h2 = h3);
assert (h3 = h4);
assert (h4 = h5)
;;
let%expect_test "Up to polymorphic variant functions behave exactly the same as fully \
bounded polymorphic variant functions"
=
let module H : sig
val h1 : [%hash: [ `A | `B ]]
val h2 : [%hash: [< `A | `B ]]
val h3 : [%hash: [< `A | `B > `A ]]
end = struct
let h1 = [%hash: [ `A | `B ]]
let h2 = [%hash: [< `A | `B ]]
let h3 = [%hash: [< `A | `B > `A ]]
end
in
let open H in
assert (h1 `A = h2 `A);
assert (h1 `A = h3 `A);
assert (h1 `B = h2 `B);
assert (h1 `B = h3 `B)
;;
|