Journey of Implicits in Scala — part 2

Type Annotations in Scala

Photo by Mark Duffel on Unsplash
  1. Introduction to implicit methods or variable definitions and method parameter lists.
  2. Type Annotations in Scala
  3. Type classes in Scala
  4. Implicit hell and how painfull it really is?
  5. Scala 3’s approach to Type Classes.

What do we mean by type

def method[A <: B](b :B) case class Container[+T]case class Printer[-T]case class Zoo[A <% Animal]case class Box[A: Animal]
object WeekDay extends Enumeration {
type WeekDay = Value
val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}
class Dog(name: String)val dog1 = new Dog ("Scooby")
val dog2 = new Dog ("Doofy")
..
case class Box[T]
Box[+Dog]
Box[-Dog]
Box[Dog <% Animal]
Box[Dog: Animal]

Type Annotations

  1. Type bound annotation
scala> class Goodsscala> case class Chocolates(name: String) extends Goodsscala> case class Mangos(name: String) extends Goodsscala> case class Human(name: String)scala> case class Box[T <: Goods](thing: T)scala> Box(Chocolates("yummy"))val res6: Box[Chocolates] = Box(Chocolates(yummy))scala> Box(Mangos("tasty"))val res7: Box[Mangos] = Box(Mangos(tasty))scala> Box(Human("name"))^error: inferred type arguments [Human] do not conform to method apply's type parameter bounds [T <: Goods]^error: type mismatch;found   : Humanrequired: T
  • Covariance Annotation
  • Contravariance Annotation
  • Invariant Annotation
class TypeConstructor[TypeParameter <% AnotherType](tipe: TypeParameter)
scala> case class Number(number: String)scala> case class Box[A <% Number](a : A)scala> Box(1)^error: No implicit view available from Int => Number.scala> implicit def intToNumber(int: Int): Number = Number(int.toString)def intToNumber(int: Int): Numberscala> Box(1)val res1: Box[Int] = Box(1)
case class Box[A](a: A)(implicit ev: A => Number)
trait Animal[A] {
def eat: String
}
case class Dog(name:String)
case class Cat(name:String)

implicit val dogAnimal: Animal[Dog] = new Animal[Dog] {
override def eat: String = "dog food"
}
implicit val catAnimal: Animal[Cat] = new Animal[Cat] {
override def eat: String = "cat food"
}

case class Box[A : Animal](animal:A) {
def eatFromBox = {
implicitly[Animal[A]].eat
}
}

// prints dog food
Box(Dog("dog")).eatFromBox
// prints dog food
Box(Cat("cat")).eatFromBox
trait TypeConstructor[A : B]
  • TypeConstructor is a type constructor that takes A as a type parameter
  • For Whatever A that is provided, there must exist a value of B[A] in the implicit scope.
trait TypeConstructor[A,B](implicit ev: B[A])

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store