Matching Type Variables Using typecase
The typecase expression in Fortress takes an expression, and selects a code path based upon the dynamic type of that expression. For example, here's some code from simplestRationalBetween:
However, sometimes you want to select a code path based not on the value of an expression like a CMP b, but instead on the value of some type variable. For example, the array1 factory for 1-dimensional arrays returns a vector if its type parameter T is numeric. The following notation is the "obvious" way to write this, but it doesn't work.
Invariant matching
Right now, in order to accomplish this we need to come up with an expression whose type mentions the type T. An obvious first attempt is this:
At the moment, the type Nothing[\T\], and every other parametric trait type in Fortress, is invariant. This means that we can't use a Nothing[\ZZ32\] where we expected a Nothing[\Number\]. There is no subtype relationship between them, so in this code if T is instantiated with ZZ32 the match will fail and we will run the else clause.
Covariant matching: Match a Function
That's not what we wanted! We want covariant matching, in which we obtain a vector if T is any subtype of Number. In Fortress, the results of functions are covariantly typed today, so if we could somehow manufacture a function whose return type was T, we could check that function's return type against Number and obtain covariant matching. That's exactly what happens in this code:
Note that we don't have a value of type T for the function to return; we work around that by explicitly declaring the return type of the function, and simply throwing an exception inside the function body. We're just creating this function and throwing it away as a technical trick to fool the Fortress type system, so the exact contents don't matter so long as they're type correct; the throw expression can have any type we want, so this is guaranteed to work. Now instead of matching against Number we match against the function type ()->Number. If T is ZZ32, we obtain a function of type ()->ZZ32. That can be used anywhere we could use a funciton ()->Number, so the match succeeds and we obtain a vector[\ZZ32,s0\]().
Contravariant Matching
If for some reason you want to do contravariant matching of types (choose this branch if the type parameter T is a supertype of the given type), you can use the same trick, but with a function whose argument type is T. This comes up in rather specialized circumstances, though, and you've usually already got an appropriately-typed function kicking around when it does.

