Union types

I think that union types allow something that sealed classes don’t: they’re able to represent SUBSETS of classes with a common ancestor or interface. Even subsets of enumerations, if their behaviour is extended.

For example, consider these classes:

interface Athlete {
}

class FootballPlayer : Athlete {
}

class Swimmer : Athlete {
}

class BasketballPlayer : Athlete {
}

// Etc.

A specific method might want to return instances of only some of those implementations:

typealias BallPlayer = FootballPlayer | BasketballPlayer;

...

fun findPlayersOfBallSports (): BallPlayer {
}

...

let player: BallPlayer = findPlayersOfBallSports ();
if (player instanceof Swimmer) {
  // ^^^ Error!!! Because "player" can only be an instance of either
  // FootballPlayer or BasketballPlayer.
}

In my opinion, it makes the code be much more powerful and self-documented.

If this behaviour were extended to instances of enum, it would also allow things like this:

enum class Device {
  SCREEN,
  KEYBOARD,
  MOUSE,
  CPU,
  RAM,
  DISK;
}

...

typealias InputDevice = Device.KEYBOARD | Device.MOUSE;

...

fun getInputDevices (): InputDevice {
}

...

let device: InputDevice = getInputDevices ();
if (device == Device.CPU) {
  // ^^^ Error!!! Because "device" can only be either
  // Device.KEYBOARD or Device.MOUSE.
}

11 Likes