# Givens, Using Clauses and Type Classes — Scala

Source: https://www.geekswithgeeks.com/en/scala/t-givens

> Use contextual abstractions to pass context and implement type classes.

## Contextual abstractions in Scala 3

Scala 3 replaces Scala 2's overloaded `implicit` keyword with clearer constructs. A **`given`** instance defines a canonical value for a type, and a **`using`** clause declares that a method needs such a value from the context: `def sorted(using ord: Ordering[A])`. The compiler finds the given automatically at the call site, though you can still pass one explicitly with `using`. This is how Scala implements **type classes**: a trait such as `trait Show[A] { def show(a: A): String }` describes a capability, givens provide instances for specific types (`given Show[Money]`), and generic code requires the capability with `[A: Show]` (a **context bound**, shorthand for a `using` parameter). Type classes add behaviour to types you do not own, such as JSON encoding, ordering, equality and serialisation, without inheritance. `derives` clauses (`case class Item(...) derives Codec`) ask a library to generate instances automatically. Givens are imported explicitly with `import x.given`, so it stays clear where they come from. Use them for genuine context (an execution context, a configuration, a type class), not to hide ordinary parameters.

## A Show type class with givens

Instances for built-in and domain types, and a generic function needing one.

```scala
trait Show[A]:
  extension (a: A) def show: String

given Show[Int] with
  extension (n: Int) def show: String = n.toString

case class Money(paise: Long)

given Show[Money] with
  extension (m: Money) def show: String = f"Rs ${m.paise / 100.0}%.2f"

given [A](using Show[A]): Show[List[A]] with      // derived instance for lists
  extension (xs: List[A]) def show: String = xs.map(_.show).mkString("[", ", ", "]")

def printAll[A: Show](items: A*): Unit =           // context bound = using Show[A]
  items.foreach(i => println(i.show))

printAll(Money(4950), Money(19900))               // Rs 49.50, Rs 199.00
println(List(Money(100), Money(250)).show)         // [Rs 1.00, Rs 2.50]

case class Gadget(name: String, pricePaise: Long)
given Ordering[Gadget] = Ordering.by[Gadget, Long](_.pricePaise)
val cheapestFirst = List(Gadget("ink", 19900), Gadget("pen", 4950)).sorted   // uses the given Ordering
```

## A plug adapter in the hotel room

A using clause is a device that needs a socket adapter. Instead of carrying one in every call, the hotel room (the scope) provides a given adapter, and the compiler plugs it in for you.

**Quiz:** What does a context bound such as [A: Show] mean?

- [ ] A must extend Show
- [ ] A is optional
- [ ] Show is a subclass of A
- [x] The method needs a given Show[A] instance from the context

*Answer:* The method needs a given Show[A] instance from the context. Context bounds are shorthand for a using parameter of type Show[A].
