scalaadvanced

Implicits and Givens Context Parameters

Use Scala 3 givens and using clauses for type classes, context parameters, and implicit conversions.

scala
// Scala 3 given/using syntax
trait Ordering[T]:
  def compare(a: T, b: T): Int
  extension (a: T)
    def <(b: T): Boolean = compare(a, b) < 0
    def >(b: T): Boolean = compare(a, b) > 0

given Ordering[Int] with
  def compare(a: Int, b: Int): Int = a - b

given Ordering[String] with
  def compare(a: String, b: String): Int = a.compareTo(b)

def max[T](a: T, b: T)(using ord: Ordering[T]): T =
  if ord.compare(a, b) >= 0 then a else b

def sorted[T](list: List[T])(using ord: Ordering[T]): List[T] =
  list.sortWith((a, b) => ord.compare(a, b) < 0)

// Type class pattern
trait JsonEncoder[T]:
  def encode(value: T): String

object JsonEncoder:
  given JsonEncoder[String] with
    def encode(value: String): String = s"\"$value\""

  given JsonEncoder[Int] with
    def encode(value: Int): String = value.toString

  given JsonEncoder[Boolean] with
    def encode(value: Boolean): String = value.toString

  given listEncoder[T](using enc: JsonEncoder[T]): JsonEncoder[List[T]] with
    def encode(value: List[T]): String =
      value.map(enc.encode).mkString("[", ",", "]")

def toJson[T](value: T)(using enc: JsonEncoder[T]): String =
  enc.encode(value)

// Context functions
type Logged[T] = Logger ?=> T

trait Logger:
  def info(msg: String): Unit

given Logger with
  def info(msg: String): Unit = println(s"[INFO] $msg")

def doWork(): Logged[String] =
  summon[Logger].info("Working...")
  "done"

@main def run(): Unit =
  println(max(10, 20))
  println(max("apple", "banana"))
  println(sorted(List(3, 1, 4, 1, 5, 9)))

  println(toJson("hello"))
  println(toJson(42))
  println(toJson(List(1, 2, 3)))
  println(toJson(List("a", "b", "c")))

  println(doWork())

Use Cases

  • Type class pattern for ad-hoc polymorphism
  • Dependency injection via context parameters
  • JSON serialization with type classes

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.