Skip to content

Instantly share code, notes, and snippets.

@derrickturk
Created May 23, 2022 15:06
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 derrickturk/08d5a3ac2511912ca89c054d98d11573 to your computer and use it in GitHub Desktop.
Save derrickturk/08d5a3ac2511912ca89c054d98d11573 to your computer and use it in GitHub Desktop.
fun with extensible variants, including extensible GADTs
(* extensible variant types, including GADTs
* not to be confused with polymorphic variants
*)
type extend_me = ..
type extend_me += This
type extend_me += That of int
type extend_me += TheOther of string
let print_extend_me = function
| This -> "this"
| That x -> "that " ^ string_of_int x
| TheOther s -> "the other \"" ^ s ^ "\""
| _ -> "something we don't know about yet"
type 'a polymorph_me = ..
type 'a polymorph_me += Untagged of 'a
type 'a polymorph_me += Tagged of string * 'a
let print_polymorph_me = function
| Untagged x -> "an untagged thing"
| Tagged (lbl, x) -> "a thing tagged \"" ^ lbl ^ "\""
| _ -> "something we don't know about yet"
type 'a gadt_me = ..
type _ gadt_me += Literal: 'a -> 'a gadt_me
type _ gadt_me += Add: int gadt_me * int gadt_me -> int gadt_me
type _ gadt_me += IsZero: int gadt_me -> bool gadt_me
type _ gadt_me +=
IfThenElse: bool gadt_me * 'a gadt_me * 'a gadt_me -> 'a gadt_me
let rec eval_gadt_me: type a. a gadt_me -> a = function
| Literal x -> x
| Add (x, y) -> eval_gadt_me x + eval_gadt_me y
| IsZero x -> eval_gadt_me x = 0
| IfThenElse (c, e_if, e_else) ->
if eval_gadt_me c
then eval_gadt_me e_if
else eval_gadt_me e_else
| _ -> raise (Invalid_argument "we can't magic an 'a into existence")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment