I never used them, but I think you want to work with GADT (this answer is for OCaml):
type ts type vs type 'a symbol = | TypeSymbol : {id : string} -> ts symbol | VariableSymbol : {id : string; ty : ts symbol} -> vs symbol | FunctionSymbol : {id : string; params : vs symbol; ty : ts symbol} -> 'a symbol;; (*don't use "type" as a field name since it a keyword of OCaml*)
As you can see, this allows me to specify exactly with which constructors I build my constructors.
Now that I want to use them:
# let t = TypeSymbol {id = "a"};; val t : ts symbol = TypeSymbol {id = "a"} # let v = VariableSymbol {id = "b"; ty = t};; val v : vs symbol = VariableSymbol {id = "b"; ty = TypeSymbol {id = "a"}} # let ve = VariableSymbol {id = "c"; ty = v};; Characters 41-42: let ve = VariableSymbol {id = "c"; ty = v};; ^ Error: This expression has type vs symbol but an expression was expected of type ts symbol Type vs is not compatible with type ts
As you can see, OCaml will not allow me to create a character with the VariableSymbol constructor if I try to build it with something other than TypeSymbol .
See here for guidance and good luck with their use.
source share