compiler: Add user-defined type constructors

This allows for Typed Racket style user-defined type constructors. For
example, the following would be exactly equivalent to the (Listof)
primitive constructor:

(define-type (Listof MT) (Rec LT (U <empty-list> (Pair MT LT))))

This is implemented by storing the uninterpreted data from the type
definition along with the argument symbols. When a type constructor is
applied its type definition is rescoped to include the new types from
the arguments and then interpreted using ExtractType. This means errors
are only raised once a type constructor is applied but it has the
benefit of allowing for a very simple and unintrusive implementation.

In the future we may want to allow type constraints on type constructor
arguments. This provides no additional safety as it's always possible to
manually construct a type but could make type constructors a bit more
self-documenting.