CSC 302: type-case
From CSWiki
A type-case expression is a form of conditional in which the branches correspond to the variants of a data type introduced through define-type, so that the subexpression chosen for evaluation depends on which variant a specified value belongs to.
Here's an example, from page 13 of our textbook:
(type-case AE an-ae (num (n) n) (add (l r) (+ (calc l) (calc r))) (sub (l r) (- (calc l) (calc r))))
The type-case expression first evaluates its second subexpression -- in this case, an-ae -- and confirms that the value belongs to the data type named by its first subexpression (AE). It then determines which variant of that data type the value belongs to and selects the num, add, or sub clause accordingly. Within that clause, the name of the variant is followed by a list of identifiers, the length of which must be the same as the number of fields in the variant. These identifiers are bound to the values in those fields. Finally, the remaining expressions in the clause are evaluated, and the value of the last one becomes the value of the entire type-case expression.
Code approximately equivalent to the example above could be written without type-case:
(cond ((not (AE? an-ae))
(error "This value is not of type AE."))
((num? an-ae)
(let ((n (num-n an-ae)))
n))
((add? an-ae)
(let ((l (add-lhs an-ae))
(r (add-rhs an-ae)))
(+ (calc l) (calc r))))
((sub? an-ae)
(let ((l (sub-lhs an-ae))
(r (sub-rhs an-ae)))
(+ (calc l) (calc r)))))
However, we're going to be using this pattern frequently, and type-case expresses the ideas more clearly and more concisely.
In addition to clauses for variants of the data type, a type-case expression can end with an else clause, consisting of the keyword else and one or more expressions. A type-case expression must contain either a clause for every variant or an else-clause, but not both.

