My first GADT and need help - probably pretty straightforward

Seems I have a need for a GADT. In the overly simplified code below, I guess I can avoid writing a h_find_xxx function per variant in data_t, while still getting the carried data without the variant tag.
But this is my very very first GADT and Iā€™m a bit shy^H^H^H inexperimented :-O, how do I write this GADT and a generic h_find_untagged function?

:slight_smile:

Thanks in advance

let len = 1024

type time_t = float array * int * int * int

type data_t =
    | Time of time_t
    | Spectrum of Complex.t array
    | Magnitude of float array

type cached_t = Room | Room_phase | Normalized | Smoothed | Eq_minphase

exception CacheDataType

let src_serial = ref 0
let sid () = !src_serial
let sincr () =
    incr src_serial

let hcache = Hashtbl.create 32

let h_add cache_id (chan: int) (data: data_t) =
    Hashtbl.add hcache (cache_id, chan, sid ()) data

let h_find (cache_id: cached_t) chan =
    Hashtbl.find hcache (cache_id, chan, sid ())

let h_find_spectrum cache_id chan =
    match (h_find cache_id chan) with
    | Spectrum cplx -> cplx
    | _ -> raise CacheDataType

let h_find_magnitude cache_id chan =
    match (h_find cache_id chan) with
    | Magnitude mag -> mag
    | _ -> raise CacheDataType

let room_spectrum head chan =
    try h_find_spectrum Room chan
    with Not_found -> (
        let out = Array.make len Complex.zero in
        h_add Room chan (Spectrum out); out
    )

let room_normalized head chan =
    try h_find_magnitude Normalized chan
    with Not_found -> (
        let norm = Array.make len 0. in
        h_add Normalized chan (Magnitude norm) ; norm
    )

The usual construction for tag gadt for variants goes like this:

module Tag = struct
  type 'a t =
  | Time: time_t t
  | Spectrum: Complex.t array t
|   Magnitude: float array t
end

let extract (type a) (tag:a Tag.t) data : a option =
  match tag, data with
  | Tag.Time, Time t -> Some t
  | Tag.Spectrum, Spectrum s -> Some s
  | Tag.Magnitude, Magnitude m -> Some m
  | _ -> None

let find tag c chan = extract tag (h_find c chan)