13 Pattern matching unions
Similarly as with tuples, pattern matching is the only way to get
to the value of union. Union patterns consists of field name followed
by nothing, []
, pattern enclosed in []
or tuple pattern.
This mimics ways, one can construct union value.
Following example utilizes pattern matching in simple symbolic expression
computations environment.
union exp {
int Const;
void Var;
*[exp, exp] Add;
*[exp, exp] Sub;
*[exp, exp] Mul;
*[exp, exp] Div;
}
int compute(exp e, int v)
{
switch e {
case Const[x] : return x;
case Var : return v;
case Add[e1, e2] : return compute(e1, v) + compute(e2, v);
case Mul[e1, e2] : return compute(e1, v) * compute(e2, v);
case Div[e1, e2] : return compute(e1, v) / compute(e2, v);
case Sub[e1, e2] : return compute(e1, v) - compute(e2, v);
}
}
exp diff(exp e)
{
switch e {
case Const[_] : return Const[0];
// both Var and Var[] are legal
case Var[] : return Const[1];
case Add[e1, e2] : return Add[diff(e1), diff(e2)];
case Sub[e1, e2] : return Sub[diff(e1), diff(e2)];
case Div[e1, e2] :
exp up = Sub[Mul[diff(e1), e2], Mul[e1, diff(e2])];
exp down = Mul[e2, e2];
return Div[up, down];
case Mul[e1, e2] :
return Add[Mul[diff(e1), e2], Mul[e1, diff(e2])];
}
}
13.1 What happen to C's switch and enums?!?
Hmm... they are still there:
union color {
void Red;
void Green;
void Blue;
}
This is roughly equivalent of C's:
typedef enum {
Red,
Green,
Blue
} color
Then we do:
string color_name(color c)
{
string r;
switch (c) {
case Red:
r = "red";
case Green:
r = "green";
// Blue[] is also legal
case Blue:
r = "blue";
}
return r;
}
This looks almost like C, modulo one little issue. There is no
fall through. Each case is separate branch or program
execution. One doesn't need to write break statements.
In fact, break would break loop enclosing switch,
if there is any!
13.2 Fall through disclaimer
If you don't like the no-fall-through clause, please first consider
following snippet of code:
switch e {
case Mult[e1, e2]:
// here we do fall through
case Const[x]:
// hmm... what does x mean, if we fall through from Mult[...]?
// and what can e1 and e2 mean here, if we didn't fall
// through?
}
Because case can bind new variables, it has to introduce
new scope. So fall through is impossible.