Created
July 16, 2022 19:02
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(** 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