Given Priority
Given priority is the rule that picks one given when two givens could fit a call. A specific instance wins over a general instance.
The specific instance wins for Int
Formatters holds a specific Formatter for Int and a general Formatter in a parent trait. Summon for Int picks the specific one.
trait Formatter[T]:
def format(x: T): String
trait LowPriority:
given [T]: Formatter[T] with
def format(x: T): String = "any:" + x.toString
object Formatters extends LowPriority:
given Formatter[Int] with
def format(x: Int): String = "int:" + x.toString
@main def main(): Unit =
import Formatters.given
println(summon[Formatter[Int]].format(7))A type with no specific instance uses the general one
String has no specific Formatter. Summon for String falls back to the general instance.
trait Formatter[T]:
def format(x: T): String
trait LowPriority:
given [T]: Formatter[T] with
def format(x: T): String = "any:" + x.toString
object Formatters extends LowPriority:
given Formatter[Int] with
def format(x: Int): String = "int:" + x.toString
@main def main(): Unit =
import Formatters.given
println(summon[Formatter[String]].format("hi"))The general instance also covers Double
Double also has no specific Formatter. The general instance formats it the same way.
trait Formatter[T]:
def format(x: T): String
trait LowPriority:
given [T]: Formatter[T] with
def format(x: T): String = "any:" + x.toString
object Formatters extends LowPriority:
given Formatter[Int] with
def format(x: Int): String = "int:" + x.toString
@main def main(): Unit =
import Formatters.given
println(summon[Formatter[Double]].format(2.5))Example
trait Formatter[T]:
def format(x: T): String
trait LowPriority:
given [T]: Formatter[T] with
def format(x: T): String = "any:" + x.toString
object Formatters extends LowPriority:
given Formatter[Int] with
def format(x: Int): String = "int:" + x.toString
@main def main(): Unit =
import Formatters.given
println(summon[Formatter[Int]].format(7))
println(summon[Formatter[String]].format("hi"))
println(summon[Formatter[Double]].format(2.5))Key points
- Specific instance: an instance written for one exact type, such as Int.
- General instance: an instance written for any type, using a type parameter.
- Low-priority trait: a parent trait that holds the general instance.
- Specific wins: when both instances fit, the compiler picks the specific one.
- General fallback: a type with no specific instance still gets the general instance.
In this example, the trait describes a Formatter. The parent trait holds the general instance. The object holds the specific instance for Int. The import brings both instances into scope. The three prints show the specific format for Int and the general format for a word and a number.
Note
without the low-priority trait, two fitting givens would clash instead of ranking.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Scastie
Exercise
Formatters has a specific Formatter for Int and a general Formatter in a low-priority trait. Which instance does summon for Int pick?