[MLton] SXML datatype definitions and the variables that use
them
Matthew Fluet
fluet@cs.cornell.edu
Thu, 15 Jun 2006 17:29:54 -0400 (EDT)
> My understanding of how datatype definitions are made is that they live in
> the top level Program structure and are simply a vector of Tycon.t * {con:
> Con.t * arg: Type.t option} vector each of which represents the definition
> of one datatype where {Con.t * Type.t option} a specific case (or arm) of
> that datatype.
Pretty much, although it is a record, rather than a tuple; from the
SXML_TREE (= XML_TREE) signature, you can see that
structure Program:
sig
datatype t =
T of {body: Exp.t,
datatypes: {cons: {arg: Type.t option,
con: Con.t} vector,
tycon: Tycon.t,
tyvars: Tyvar.t vector} vector,
(* overflow is SOME only after exceptions have been
* implemented.
*)
overflow: Var.t option}
...
end
In the SXML intermediate language, the invariant is that 'tyvars' is
always the empty vector.
> My question is if I construct a new datatype definition, for example,
> datatype foo = A of unit | B of int
> and have a variable
> val bar = A()
> How do I construct the type of bar?
>
> It seems logical that I would use Type.con and pass it the foo Tycon, but
> I'm unsure what the second argument (which is a vector of Type.t) does, or
> if this is even the correct thing to be doing.
The second argument is a vector of types to instantiate the type
constructor; but, in SXML, there are no polymorphic type constructors, so
pass the empty vector.
For example, in XML, if you wanted to construct the following:
datatype 'a foo = A of unit | B of 'a
val bar : int foo = A ()
you would do:
open XmlTree
val foo = Tycon.newString "foo"
val a = Tyvar.newNoname {equality = false}
val A = Con.newString "A"
val B = Con.newString "B"
val fooDT = {cons = Vector.new2
({arg = SOME (Type.unit)},
con = A},
{arg = SOME (Type.var a),
con = B}),
tycon = foo,
tyvars = Vector.new1 (a)}
val u = Var.newString "u"
val uDec = Dec.MonoVal
{exp = PrimApp.Tuple (Vector.new0 ()),
ty = Type.unit,
var = u}
val bar = Var.newString "bar"
val typeVec = Vector.new1 (Type.defaultWord)
val barDec = Dec.MonoVal
{exp = PrimApp.ConApp
{arg = u,
con = A,
targs = typeVec},
ty = Type.con (foo, typeVec),
var = bar}
In SXML, the datatype and variables must be monomorphic; so, if you wanted
to construct the following:
datatype foo = A of unit | B of int
val bar : foo = A ()
you would do:
open SxmlTree
val foo = Tycon.newString "foo"
val A = Con.newString "A"
val B = Con.newString "B"
val fooDT = {cons = Vector.new2
({arg = SOME (Type.unit)},
con = A},
{arg = SOME (Type.defaultWord),
con = B}),
tycon = foo,
tyvars = Vector.new0 ()}
val u = Var.newString "u"
val uDec = Dec.MonoVal
{exp = PrimApp.Tuple (Vector.new0 ()),
ty = Type.unit,
var = u}
val bar = Var.newString "bar"
val barDec = Dec.MonoVal
{exp = PrimApp.ConApp
{arg = u,
con = A,
targs = Vector.new0 ()},
ty = Type.con (foo, Vector.new0 ()),
var = bar}