Skip to content

Instantly share code, notes, and snippets.

@zshipko
Created July 16, 2022 19:02
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 zshipko/4db08fb6e8427a71be5d6978b3afc431 to your computer and use it in GitHub Desktop.
Save zshipko/4db08fb6e8427a71be5d6978b3afc431 to your computer and use it in GitHub Desktop.
An example using `Obj` to index a record using an enum or int
(** An example using [Obj] index a record using an enum or int *)
module type Record = sig
(** [Record] defines two types, [t] and ['a field], [t] is the record type and ['a field]
defines the representation used for fields *)
type t
(** record type *)
type 'a field
(** field type *)
val int_of_field : 'a field -> int
(** [int_of_field] converts from ['a field] to [int], this is used as the index for the call to
[Obj.field] and [Obj.set_field] *)
end
module Field = struct
(** Default implementations for [int_of_field] *)
module Enum = struct
(** [int_of_field] that can be used for enum fields *)
let int_of_field x = Obj.magic x
end
module Int = struct
(** [int_of_field] that can be used for int fields *)
let int_of_field x = x
end
end
module type S = sig
include Record
val get : t -> 'a field -> 'a
val set : t -> 'a field -> 'a -> unit
end
module Make (Record : Record) :
S with type t = Record.t and type 'a field = 'a Record.field = struct
include Record
(** Get a field *)
let get t field =
let index = Record.int_of_field field in
let obj = Obj.repr t in
Obj.field obj index |> Obj.obj
(** Set a field *)
let set t field value =
let index = Record.int_of_field field in
let obj = Obj.repr t in
Obj.set_field obj index (Obj.repr value)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment