I was looking at Dotty
docs under Contextual Abstractions
page and I saw the Given Instances
.
Given instances (or, simply, "givens") define "canonical" values of certain types that serve for synthesizing arguments to given clauses. Example:
trait Ord[T] {
def compare(x: T, y: T): Int
def (x: T) < (y: T) = compare(x, y) < 0
def (x: T) > (y: T) = compare(x, y) > 0
}
given intOrd: Ord[Int] {
def compare(x: Int, y: Int) =
if (x < y) -1 else if (x > y) +1 else 0
}
given listOrd[T]: (ord: Ord[T]) => Ord[List[T]] {
def compare(xs: List[T], ys: List[T]): Int = (xs, ys) match {
case (Nil, Nil) => 0
case (Nil, _) => -1
case (_, Nil) => +1
case (x :: xs1, y :: ys1) =>
val fst = ord.compare(x, y)
if (fst != 0) fst else compare(xs1, ys1)
}
}
But this example from docs never explains how to use given
. I pulled the test Dotty
example project and try yo use it, but I don't quite understand it.
Is it a new keyword ? Do we import it ? Or am I missing something .
Here's an example of using the given
instance. Let's say we want to compare two integers, and see which is bigger than the other. We can leverage the already defined intOrd
above and write:
def whichIsBigger[T](x: T, y: T)(given ord: Ord[T]): String = {
ord.compare(x, y) match {
case -1 => s"$x is less than $y"
case 0 => s"$x and $y are equal"
case 1 => s"$x is greater than $y"
}
}
println(whichIsBigger(2, 1))
Which yields:
2 is greater than 1
We were able to do this because there was a named given instance in scope, otherwise, the compiler would have complained it doesn't have an Ord[Int]
.
Is it a new keyword ? Do we import it ? Or am I missing something.
It is a new keyword, one which replaces a specific part of implicit
definition in Scala 2. If this was Scala 2, we would have written:
implicit val intOrd: Ord[Int] = new Ord[Int] {
def compare(x: Int, y: Int) =
if (x < y) -1 else if (x > y) 1 else 0
}
def whichIsBigger[T](x: T, y: T)(implicit ord: Ord[T]): String