Proposal for Multi-level Enums

The most elegant way to model (at least some of these cases) without multi-level enums that I have found so far is using union types:

  1. SizeInfo:
type SizeInfo = Atomic | Bounded

enum Atomic {
  case Infinite
  case Precise(n: Int)
}

case class Bounded(bound: Int)
  1. Generalization of Either to include “Inclusive OR”
type AndOr[+A, +B] = Both[A, B] | Either[A, B]

case class Both[+A, +B](left: A, right: B)

enum Either[+A, +B]:
  case Left[+A, +B](value: A) extends Either[A, B]
  case Right[+A, +B](value: B) extends Either[A, B]
  1. JSON:
type JsValue = Obj | Arr | Primitive

case class Obj(fields: Map[String, JsValue])
case class Arr(elems: Array[JsValue])

type Primitive = Str | Num | JsNull.type | Bool

case class Str(str: String)
case class Num(bigDecimal: BigDecimal)
case object JsNull

enum Bool(boolean: Boolean):
    case True extends Bool(true)
    case False extends Bool(false)

The second example from the original post (the Hierarchy of Reals/Rationals/Integers/Naturals) is more tricky using Union Types as the top-level type has a shared member.

2 Likes