- implicit vals
implicit val ec: ExecutionContext = ExecutionContext.global
Future {
def apply[T](body: => T)(implicit executor: ExecutionContext): Future[T] = {...}
}
Scala 2
val myFuture: Future[Int] = Future {
println("Finding the answer...")
42
}
?
?
- using/given
val myFuture: Future[Int] = Future {
println("Finding the answer...")
42
}
Scala 3
given ec: ExecutionContext = ExecutionContext.global
Future {
def apply[T](body: => T)(using executor: ExecutionContext): Future[T] = {...}
}
?
?
object other_package {
case class Book(title: String, pages: Int)
}
val book = Book("Winnie-the-Pooh", 160)
myBook.qualifiesForChallenge //true
val book = Book("Too short", 5)
myBook.qualifiesForChallenge //false
implicit class Qualifier(b: Book) {
def qualifiesForChallenge: Boolean = b.pages > 20
}
?
- implicit classes
Scala 2
- extension methods
object other_package {
case class Book(title: String, pages: Int)
}
val book = Book("Winnie-the-Pooh", 160)
myBook.qualifiesForChallenge //true
val book = Book("Too short", 5)
myBook.qualifiesForChallenge //false
?
extension (b: Book)
def qualifiesForChallenge = b.pages > 20
Scala 3
trait Scorable[T] {
def score(t: T): Int
}
val book = Book("Dune", 600)
val initialScore = CurrentScore(0).addItem(book) // CurrentScore(600)
val article = Article("Understanding type classes")
val newScore = initialScore.addItem(article) // CurrentScore(601)
?
- implicit val/object/def (with context bounds and implicitly)
implicit val scorableBook = new Scorable[Book] {
override def score(b: Book): Int = b.pages
}
implicit val scorableArticle = new Scorable[Article] {
override def score(t: Article): Int = 1
}
case class CurrentScore(value: Int) {
def addItem[T: Scorable](item: T): CurrentScore =
CurrentScore(value + implicitly[Scorable[T]].score(item))
}
Scala 2
?
trait Scorable[T] {
def score(t: T): Int
}
val book = Book("Dune", 600)
val initialScore = CurrentScore(0).addItem(book) // CurrentScore(600)
val article = Article("Understanding type classes")
val newScore = initialScore.addItem(article) // CurrentScore(601)
- implicit val/object/def (with implicit parameters)
implicit val scorableBook = new Scorable[Book] {
override def score(b: Book): Int = b.pages
}
implicit val scorableArticle = new Scorable[Article] {
override def score(t: Article): Int = 1
}
case class CurrentScore(value: Int) {
def addItem[T](item: T)(implicit scoring: Scorable[T]): CurrentScore =
CurrentScore(value + scoring.score(item))
}
Scala 2
- given instances (with context bounds and summon)
?
given Scorable[Book] with {
override def score(b: Book): Int = b.pages
}
given Scorable[Article] with {
override def score(t: Article): Int = 1
}
case class CurrentScore(value: Int) {
def addItem[T: Scorable](item: T): CurrentScore =
CurrentScore(value + summon[Scorable[T]].score(item))
}
trait Scorable[T] {
def score(t: T): Int
}
Scala 3
val book = Book("Dune", 600)
val initialScore = CurrentScore(0).addItem(book) // CurrentScore(600)
val article = Article("Understanding type classes")
val newScore = initialScore.addItem(article) // CurrentScore(601)
- given instances (with using)
given Scorable[Book] with {
override def score(b: Book): Int = b.pages
}
given Scorable[Article] with {
override def score(t: Article): Int = 1
}
case class CurrentScore(value: Int) {
def addItem[T](item: T)(using scoring: Scorable[T]): CurrentScore =
CurrentScore(value + scoring.score(item))
}
trait Scorable[T] {
def score(t: T): Int
}
val book = Book("Dune", 600)
val initialScore = CurrentScore(0).addItem(book) // CurrentScore(600)
val article = Article("Understanding type classes")
val newScore = initialScore.addItem(article) // CurrentScore(601)
Scala 3
- implicit def
case class Item(value: String) extends AnyVal
def print(item: Item): Unit = println(s"*** ${item.value} ***")
val book = Book("Dune", 600)
print(book)
?
implicit def bookToItem(book: Book): Item = Item(book.title)
Scala 2
- Conversion class
case class Item(value: String) extends AnyVal
def print(item: Item): Unit = println(s"*** ${item.value} ***")
val book = Book("Dune", 600)
print(book)
?
given Conversion[Book, Item] with
def apply(book: Book): Item = Item(book.title)
Scala 3
- importing implicits
import scala.concurrent.ExecutionContext.Implicits.*
val future = Future(42) //OK
Scala 2
- importing givens
import scala.concurrent.ExecutionContext.Implicits.*
val future = Future(42) //error
import scala.concurrent.ExecutionContext.Implicits.given
val future = Future(42) //OK
Scala 3
import scala.concurrent.ExecutionContext.Implicits.{given, *}
val future = Future(42) //OK
trait SeqOps (...) {
def sorted[B](implicit ord: Ordering[B]): Seq = ...
}
- mandatory names
implicit val byTitle: Ordering[Book] = (x: Book, y: Book) => x.title.compareTo(y.title)
val myBooks = Seq(Book("Dune", 600), Book("Winnie-the-Pooh", 160))
myBooks.sorted
?
Scala 2
trait SeqOps (...) {
def sorted[B](using ord: Ordering[B]): Seq = ...
}
- anonymous givens
given byTitle: Ordering[Book] = (x: Book, y: Book) => x.title.compareTo(y.title)
val myBooks = Seq(Book("Dune", 600), Book("Winnie-the-Pooh", 160))
myBooks.sorted
given Ordering[Book] = (x: Book, y: Book) => x.title.compareTo(y.title)
?
?
Scala 3
could not find implicit value for evidence parameter of type
org.example.TypeClassesFullContextBoundsExample.Scorable[org.example.Domain.Book]
Scala 2
The following import might fix the problem:
import concurrent.ExecutionContext.Implicits.global
no implicit argument of type
org.example.TypeClassesFullExample.Scorable[org.example.domain.Book] was found
for parameter scoring of method addItem in class CurrentScore
Scala 3
given Finished[Presentation] with {
override def ask(q: Question): Unit = q.ask()
}
10% off:
Magda10