scalaadvanced
Type Class Derivation with Mirrors
Derive type class instances automatically using Scala 3 Mirrors and inline metaprogramming.
scalaPress ⌘/Ctrl + Shift + C to copy
import scala.deriving.Mirror
import scala.compiletime.{constValue, erasedValue, summonInline}
// Type class to derive
trait Show[T]:
def show(value: T): String
object Show:
given Show[Int] with
def show(value: Int): String = value.toString
given Show[String] with
def show(value: String): String = s"\"$value\""
given Show[Boolean] with
def show(value: Boolean): String = value.toString
given Show[Double] with
def show(value: Double): String = f"$value%.2f"
// Show for List
given [T](using s: Show[T]): Show[List[T]] with
def show(value: List[T]): String =
value.map(s.show).mkString("[", ", ", "]")
// Show for Option
given [T](using s: Show[T]): Show[Option[T]] with
def show(value: Option[T]): String = value match
case Some(v) => s"Some(${s.show(v)})"
case None => "None"
// Derive for products (case classes)
inline def showProduct[T](value: T, labels: List[String])(
using m: Mirror.ProductOf[T]
): String =
val elems = value.asInstanceOf[Product].productIterator.toList
val pairs = labels.zip(elems).map { (label, elem) =>
s"$label = $elem"
}
s"${value.getClass.getSimpleName}(${pairs.mkString(", ")})"
// For simple demo, manual derivation
inline given derived[T](using m: Mirror.Of[T]): Show[T] =
new Show[T]:
def show(value: T): String =
value.toString // simplified; full impl uses compiletime
// Manual instances for our types
case class Point(x: Double, y: Double) derives Show
case class Color(r: Int, g: Int, b: Int) derives Show
case class Pixel(point: Point, color: Color) derives Show
// Custom Show with nice formatting
given Show[Point] with
def show(value: Point): String = f"(${value.x}%.1f, ${value.y}%.1f)"
given Show[Color] with
def show(value: Color): String =
f"rgb(${value.r}, ${value.g}, ${value.b})"
given Show[Pixel] with
def show(value: Pixel): String =
s"Pixel at ${summon[Show[Point]].show(value.point)} color=${summon[Show[Color]].show(value.color)}"
def printShow[T: Show](value: T): Unit =
println(summon[Show[T]].show(value))
@main def run(): Unit =
printShow(42)
printShow("hello")
printShow(true)
printShow(3.14159)
printShow(List(1, 2, 3))
printShow(Option("test"))
printShow(Option.empty[String])
val pixel = Pixel(Point(10.5, 20.3), Color(255, 128, 0))
printShow(pixel)
val points = List(Point(1, 2), Point(3, 4), Point(5, 6))
printShow(points)Use Cases
- Automatic codec generation
- Reducing boilerplate with derivation
- Generic programming utilities
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
scalaadvanced
Inline and Compile-Time Metaprogramming
Use Scala 3 inline, transparent inline, and compiletime for compile-time computation and code generation.
Best for: Compile-time computation
#scala#inline
scalaadvanced
Type-Level Programming with Tuples
Work with heterogeneous collections: named tuples, type-safe access, and compile-time operations.
Best for: Generic programming with Mirrors
#scala#type-level
scalabeginner
Scala Hello World Application
Create a basic Scala application with main method, string interpolation, and val/var basics.
Best for: Getting started with Scala
#scala#basics
scalabeginner
Pattern Matching Fundamentals
Use Scala pattern matching with guards, type patterns, tuple patterns, and nested extractors.
Best for: Control flow with pattern matching
#scala#pattern-matching