Variant subset matching

I have run into this case a few times, wonder if there is a way to do the following better:

public type SubType = {
    #one;
    #two;
};
public type SuperType = {
  #three;
};

switch (superType) {
  case (#three) processThree();
  case (#two) processSubType(#two); 
  case (#one) processSubType(#one);
};

public func processSubType(subType : SubType) {
    ...
};

It gets tedious to list out all the subtypes that all do one thing. I want to just make one call like:

switch (superType) {
  case (#three) processThree();
  // Remaining cases have to be the subtype
  case (subType) processSubType(subType); 
};

Or maybe a type pattern check like:

switch (superType) {
  case (#three) processThree();
  case (subType is SubType s) processSubType(s);
};

Any alternatives?

Unfortunately, no, all cases in a switch are expected to have the same type, and there are no downcasts in Motoko, which is would effectively be (values do not carry runtime type information).

In theory, there are ways to enrich static typing of pattern matching to compute “type subtraction” to refine types, but they are very complex, because patterns can be arbitrarily nested. And the presence of general subtyping does not make it easier. I am not aware of a language with subtyping that would support this.

2 Likes