enum Color:
case Red, Green, Blue
Color.Red
Color.values // Array(Red, Green, Blue)
Color.valueOf("Green")
Color.Red.ordinal // 0
14.2 Enums with parameters & members
enum Planet(val mass: Double, val radius: Double):
case Mercury extends Planet(3.303e+23, 2.4397e6)
case Earth extends Planet(5.976e+24, 6.37814e6)
private final val G = 6.67300e-11
def surfaceGravity: Double = G * mass / (radius * radius)
Planet.Earth.surfaceGravity
14.3 ADTs with enums
enum Shape:
case Circle(radius: Double)
case Rectangle(w: Double, h: Double)
case Triangle(a: Double, b: Double, c: Double)
def area(s: Shape): Double = s match
case Shape.Circle(r) => math.Pi * r * r
case Shape.Rectangle(w, h) => w * h
case Shape.Triangle(a, b, c) =>
val p = (a + b + c) / 2
math.sqrt(p * (p - a) * (p - b) * (p - c))
14.4 Generic ADTs
enum Tree[+A]:
case Leaf
case Node(left: Tree[A], value: A, right: Tree[A])
def size: Int = this match
case Leaf => 0
case Node(l, _, r) => l.size + 1 + r.size
enum Result[+E, +A]:
case Ok(value: A)
case Err(error: E)
14.5 Sealed traits (Scala 2 style ADTs, still common)
sealed trait Json
case object JNull extends Json
case class JBool(b: Boolean) extends Json
case class JNum(n: Double) extends Json
case class JStr(s: String) extends Json
case class JArr(items: List[Json]) extends Json
case class JObj(fields: Map[String, Json]) extends Json
def render(j: Json): String = j match
case JNull => "null"
case JBool(b) => b.toString
case JNum(n) => n.toString
case JStr(s) => s"\"$s\""
case JArr(xs) => xs.map(render).mkString("[", ",", "]")
case JObj(fs) => fs.map((k, v) => s"\"$k\":${render(v)}").mkString("{", ",", "}")
14.6 Making illegal states unrepresentable
enum Connection:
case Disconnected
case Connecting(attempt: Int)
case Connected(sessionId: String)
14.7 Java-compatible enums
enum Level extends java.lang.Enum[Level]:
case Low, High