<h1>Variant Types</h1>

The module <tt>srfi-99-variants</tt> exports convenience syntax to
create variant types and to destructure their instances. A variant
type is a record type with a set of sealed subtypes.

<h2>Defining Variant Types</h2>

A variant type can be defined using the syntax

<verbatim>
  (define-variant-type [rtd | (rtd option ...)] predicate
    (variant field ...)
    ...)
</verbatim>

The syntax elements <tt>rtd</tt>, <tt>option</tt> and
<tt>predicate</tt> are used just like the corresponding elements of
the <tt>define-record-type</tt> syntax. The new record type has no
fields and no direct constructor.

Each <tt>variant</tt> identifier is bound to the constructor procedure
of a sealed subtype of <tt>rtd</tt>. The record type descriptor of the
subtype is attached as procedure data to the constructor.

The variant subtypes are opaque if and only if the base type is
opaque.

Single variants can also be defined separately using the macro <tt>define-variant-constructor</tt>.

<h2>Matching variant types</h2>

Given an instance <tt>v</tt> of a variant type <tt>rtd</tt> you can
use the following syntax to match on the different possible variants
of the instance:

<verbatim>
  (variant-case rtd v
    ((variant field ...)
     body ...)
    ...
    [(else
      body ...)])
</verbatim>

The form first ensures that <tt>v</tt> is indeed an instance of
<tt>rtd</tt>, raising a type error otherwise.

Each <tt>variant</tt> designates a variant constructor, each
<tt>field</tt> is an identifier to be bound to the corresponding,
identically named field of the variant instance. If any of the variant
clauses matches the type of <tt>v</tt>, the corresponding body is
evaluated and the result is returned from the <tt>variant-case</tt>
form.

If none of the variant clauses match the type of <tt>v</tt>, the else
clause is executed instead. If no else clause is present either, an
error is raised indicating that no matching variant was found.