Skip to content

Instantly share code, notes, and snippets.

@mimoo
Last active March 6, 2022 19:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mimoo/bceb346db8e7259046e5ee8090a6bbba to your computer and use it in GitHub Desktop.
Save mimoo/bceb346db8e7259046e5ee8090a6bbba to your computer and use it in GitHub Desktop.
OCaml bug: you might think that deriving {hash, eq} is enough to use a custom record in a hashtable. Think again!
(library
(name ocaml_bug)
(inline_tests)
(preprocess
(pps ppx_inline_test ppx_deriving.eq ppx_deriving_hash)))
module Oracle (SomeModule : Hashtbl.HashedType) = struct
let counter = ref 0
module Hashtbl = Hashtbl.Make (SomeModule)
let memory : int Hashtbl.t = Hashtbl.create 5
let to_bytes (t : SomeModule.t) : string =
match Hashtbl.find_opt memory t with
| Some d -> string_of_int d
| None ->
incr counter;
Hashtbl.add memory t !counter;
string_of_int !counter
end
module A = struct
type t = { a : int; b : int } [@@deriving hash, eq]
let to_bytes block =
let module Temp = Oracle (struct
type nonrec t = t
let hash = hash
let equal = equal
end) in
Temp.to_bytes block
let%test_unit "to_bytes" =
let block = { a = 1; b = 2 } in
let b1 = to_bytes block in
let b2 = to_bytes block in
assert (b1 = "1");
assert (b1 = b2);
let other_block = { block with b = 3 } in
let b3 = to_bytes other_block in
assert (b3 = "2")
end
{
"dependencies": {
"ocaml": "~4.13.1",
"@opam/dune": "*",
"@opam/ppx_inline_test": "*",
"@opam/ppx_deriving": "*",
"@opam/ppx_deriving_hash": "*"
},
"devDependencies": {
"@opam/merlin": "*"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment