Proposal for Multi-level Enums

For the Hierarchy of Reals/Rationals/Integers/Naturals example we can do something like:

type Real = Rational | Irrational
object Real:
  abstract class Type(computeDigits: Int => BigDecimal)

case class Irrational(computeDigits: Int => BigDecimal)
  extends Real.Type(computeDigits)

type Rational = Integer | Fraction
object Rational:
  abstract class Type(numerator: Int, denominator: Int)
    extends Real.Type(_ => BigDecimal(numerator) / denominator)

case class Fraction(numerator: Int, denominator: Int)
  extends Rational.Type(numerator, denominator)

enum Integer(n: Int) extends Rational.Type(n, 1):
  case Natural(n: Int) extends Integer(n)
  case Negative(n: Int) extends Integer(n)


val r1: Integer = Integer.Natural(4)
val r2: Integer = Integer.Negative(5)
val r3: Rational = Fraction(2, 4)
val r4: Irrational = Irrational(i => 2*i)

Here I introduced a common abstract class / trait for each union type that shares a common member and declare it inside an object with the same name as the union type.

As observed by @bjornregnell the union types with “shared members” relate to the discussion over at Making union types even more useful

2 Likes