Type constructor applied to arguments, and its definition.
For example, writing Tycon ("tree", [ Integer ], defns) represents int tree, for whatever tree is defined as in defns. The following defines tree as a binary tree with the parameter type stored at the leaves.
let defns =
[ { tycon = "tree"
; tyvars = ["a"]
; grammar =
Variant
{ name_kind = Capitalized
; clauses =
[ { name = "Node"
; args = Cons (Recursive ("node", [Tyvar "a"]), Empty)
}
; { name = "Leaf"
; args = Cons (Recursive ("leaf", [Tyvar "a"]), Empty)
}
]
}
}
; { tycon = "node"
; tyvars = ["a"]
; grammar = List (Many (Recursive "tree", [Tyvar "a"]))
}
; { tycon = "leaf"
; tyvars = ["a"]
; grammar = [Tyvar "a"]
}
]
;;
To illustrate the meaning of Tycon with respect to defns, and to demonstrate one way to access them, it is equivalent to expand the definition of "tree" one level and move the defns to enclosed recursive references:
Tycon ("tree", [ Integer ], defns)
-->
Variant
{ name_kind = Capitalized
; clauses =
[ { name = "Node"
; args = Cons (Tycon ("node", [Tyvar "a"], defns), Empty)
}
; { name = "Leaf"
; args = Cons (Tycon ("leaf", [Tyvar "a"], defns), Empty)
}
]
}
This transformation exposes the structure of a grammar with recursive references, while preserving the meaning of recursively-defined elements.