Types as first class citizens in OCaml

Maybe the thing you’re looking for is GADT’s

(* Given:
module Db : sig
  type t
  module Row : sig
    type t
    val get_int : t -> int -> int
    val get_string : t -> int -> string
  end

  val query : t -> string -> Row.t list
end
*)

type _ column =
  | Dep_id of int column
  | Name of string column

let to_column_name : type a. a column -> string = function
  | Dep_id -> "dep_id"
  | Name -> "name"

(* `read_all db Dep_id` returns an `int list` of all values in dep_id, and
   `read_all db Name` returns a `string` list of all values in `name` *)
let read_all db : type a. a column -> a list =
  let query = Printf.sprintf "SELECT %s FROM some_table"
                (to_column_name column) in
  Db.query db query
  |> List.map ~f:(fun row ->
    match column with
    | Dep_id -> Db.Row.get_int row 0
    | Name -> Db.Row.get_name row 0

Beyond that, maybe you’d need to look into PPX.

4 Likes