Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Given and Using

Sorting

Sorted

@main
def main(): Unit =
  val list = List(1, 5, 2, 6, 4, 3)
  val sortedList = list.sorted
  println(sortedList)

// List(1,2,3,4,5,6)

Ordering

given ordering: Ordering[Int] with
  override implicit def compare(x: Int, y: Int): Int = x - y

This is the same as the default implements of the standard libraries

Reverse Ordering

given reversedOrdering: Ordering[Int] with
  override implicit def compare(x: Int, y: Int): Int = y - x

Using

def sorting(using order: Ordering[Int])(list: List[Int]): List[Int] =
  list.sorted

Here we have a function that is using a given as parameter. When he compiler sees a using will search for a `given' of that type.

@main
def main(): Unit =
  val list = List(1,5,2,6,4,3)
  println(sorting(list))

Case Classes

case class Todo (task: String, priority: Int)
given todoOrdering: Ordering[Todo] with
  override implicit def compare(a: Todo, b: Todo): Int = 
    a.priority - b.priority
@main
def main(): Unit =
  val todoList = List(Todo("walk", 3), Todo("talk", 5), Todo("sleep", 1))
  println(todoList.sorted)

// List(Todo(sleep,1), Todo(walk,3), Todo(talk,5))

Scopes

The compiler will look for available given in scopes in the following order

  1. imported givens
  2. current scope
  3. companion object

Companion Object

object Todo:
  given todoOrdering: Ordering[Todo] with
    override implicit def compare(a: Todo, b: Todo): Int = 
      a.priority - b.priority

The ordering is added to the campanion object.
If there is no given in the current scope. The compiler will look in the companion object.

@main
def main(): Unit =
  val todoList = List(Todo("walk", 3), Todo("talk", 5), Todo("sleep", 1))
  println(todoList.sorted)

// List(Todo(sleep,1), Todo(walk,3), Todo(talk,5))

The using is found in the companion object

import given

object TodoOrdering:
  given todoOrdering: Ordering[Todo] with
    override implicit def compare(a: Todo, b: Todo): Int = 
      a.priority - b.priority

The ordering is added to another scope

@main
def main(): Unit =
  val todoList = List(Todo("walk", 3), Todo("talk", 5), Todo("sleep", 1))
  
  import TodoOrdering.given
  println(todoList.sorted)

// List(Todo(sleep,1), Todo(walk,3), Todo(talk,5))

Now we have to import the given. We can do this in two ways:

  • import TodoOrdering.todoOrdering
  • import TodoOrdering.given
  • import TodoOrdering.*

The wildcard * does not work on givens.

Rule of thumb

  • Put the most frequently used ordering in the companion object
  • Put the other orderings in separate objects with a clear names