// TODO: use this instead of #1009173 to save one field. yay! abstract sclass Either { bool isA() { false; } bool isB() { false; } A a() { throw _failMe(); } B b() { throw _failMe(); } A aOpt() { null; } B bOpt() { null; } abstract O value(); RuntimeException _failMe() { fail("Either object is of wrong type: " + shortClassName(value())); } toString { ret "Either" + (isA() ? "A" : "B") + "(" + value() + ")"; } } sclass EitherA extends Either { A value; bool isA() { true; } A a() { ret value; } A aOpt() { ret value; } O value() { ret value; } } sclass EitherB extends Either { B value; bool isB() { true; } B b() { ret value; } B bOpt() { ret value; } O value() { ret value; } }