My compiler’s AST is initially annotated with location but I dislike how location shows up in my expect tests. I’d like to strip location before testing, e.g. by replacing location with unit. This requires that my AST be parameterized on the type of annotation. For example,
...
and Output : sig
type 'n t =
| Text : string -> 'n t
| Register : 'n Register.t -> 'n t
| Register_index : 'n Register_index.t -> 'n t
| Bit_field : 'n Bit_field.t -> 'n t
| Scanner : 'n Scanner.t -> 'n t
end =
Output
and Type : sig
type (_, 'n) t =
| Register : ('n Register.t, _) t
| Register_index : ('n Register_index.t, _) t
| Bit_field : ('n Bit_field.t, _) t
| Macro : ('n Macro.t, _) t
| Memory_region : ('n Memory_region.t, _) t
| Pcode_op : ('n Pcode_op.t, _) t
| Scanner : ('n Scanner.t, _) t
[@@deriving sexp]
end =
Type
My type environment works when not parameterized but when I try to parameterize it on the type of annotation, like this
module Type_env = struct
type 'n t =
| Nil
| Cons : string * ('a, 'n) Type.t * 'a * 'n t -> 'n t
type ('a, 'b, 'na, 'nb) eq = Refl : ('a, 'a, 'na, 'na) eq
let make () = Nil
let types_equal
: type a b na nb.
(a, na) Type.t -> (b, nb) Type.t -> (a, b, na, nb) eq option
=
fun a b ->
let open Type in
match a, b with
| Register, Register -> Some Refl
| Register_index, Register_index -> Some Refl
| Bit_field, Bit_field -> Some Refl
| Macro, Macro -> Some Refl
| Memory_region, Memory_region -> Some Refl
| _, _ -> None
;;
I get an error
Error: This expression has type (a, a, 'a, 'a) eq
but an expression was expected of type (a, b, na, nb) eq
Type a = $0 Register.t is not compatible with type b = $1 Register.t
Type $0 is not compatible with type $1
Is it possible to do what I’m trying to do? How?