sclass TypeSystem { // override if you have supertype (subtype) relations in your type system // you can assume neq(a, b) bool isActualSupertypeOf(T a, T b) { false; } bool isSupertypeOf(T a, T b) { ret eq(a, b) || isActualSupertypeOf(a, b); } bool operatorCanTakeArguments(GOperator op, T... types) { ret matchTwoLists(lambda2 isSupertypeOf, reallyLazyMap(op.arguments, a -> a.type()), types); } }