Scala Implicitly

As I study about Scala, I open see implicitly. But, every time I see this, I just ignore just thinking like “It’s syntactic sugar of implicit”. This time, I write this post to really under stand this.

In Scala, implicitly is just this.


def implicitly[T](implicit e: T) = e

That’s all! implicitly is a function just get implicit e instance and return e. Then, what is an advantage of using implicitly?

Example 1

You can use implicit like this.

implicit val optionInt: Option[Int] = Some(1)
implicit val optionBoolean: Option[Boolean] = Some(true)

def getImplicitInt(implicit oInt: Option[Int]): Int = oInt.get
def getImplicitBoolean(implicit oBoolean: Option[Boolean]): Boolean = oBoolean.get

getImplicitInt
// res0: Int = 1
getImplicitBoolean
// res1: Boolean = true

Now, you can use just same by using implicitly


implicit val optionInt: Option[Int] = Some(1)
implicit val optionBoolean: Option[Boolean] = Some(true)

def getImplicitlyA[A: Option]: A = implicitly[Option[A]].get

getImplicitlyA[Int]
// res2: Int = 1
getImplicitlyA[Boolean]
// res3: Boolean = true

Implicitly can use in such situation.

Implicitly can use when you want to get implicit instance which have 1 type parameter.

As you can see above, by using ‘Implicitly[Option[Int]]’, you can get implicit instance ‘Option[Int]’. It has 1 type parameter Int.

Example 2

Then how about implicitly for the type which has no type parameter? For example, implicit can do like this.


implicit val string: String = "Hello"
implicit val boolean: Boolean = true
implicit val int: Int = 0

def getImplicitT[T](implicit t: T): T = t

getImplicitT[Int]
// res0: Int = 0

getImplicitT[String]
// res1: String = Hello

getImplicitT[Boolean]
// res2: Boolean = true

But, if you do the same with implicitly, errors occur.


def getImplicitlyT[T]: T = implicitly[T]

getImplicitlyT[Int]
getImplicitlyT[String]
getImplicitlyT[Boolean]

// compile error: not enough arguments for method implicitly: (implicit e: T)T. Unspecified value parameter e. def getImplicitlyT[T]: T = implicitly[T] ^

Yes, because I mentioned above, implicitly can be used the type which has a type parameter. Then how can we use implicitly in this situation? The answer is ‘make Id type’.


type Id[A] = A

def getImplicitlyT[T : Id]: T = implicitly[Id[T]]

getImplicitlyT[Int]
// res3: Int = 0

getImplicitlyT[String]
// res4: String = Hello

getImplicitlyT[Boolean]
// res5: Boolean = true

I make new type Id which has one type parameter. And Id[A] is same as A. So, you can use just like implicit

Context bound

Right side of function ‘getImplicitlyAt’ has type parameter(A : Option). It looks like type bound. But it is called Context bound. Type bound is ‘<:’.You can see type bound in Scala School. In context bound, it doesn’t mean that A is Option. Instead, A will be a type passing to Option.

implicit val optionInt: Option[Int] = Some(1)
implicit val optionBoolean: Option[Boolean] = Some(true)
def getImplicitOptionInt(implicit oInt: Option[Int]): Int = oInt.get
def getImplicitOptionBoolean(implicit oBoolean: Option[Boolean]): Boolean = oBoolean.get
getImplicitOptionInt
getImplicitOptionBoolean
def getImplicitlyOptionA[A: Option]: A = implicitly[Option[A]].get
getImplicitlyOptionA[Int]
getImplicitlyOptionA[Boolean]
trait Parent {
def sayHello: String
}
trait Son extends Parent {
override def sayHello: String = "Hello! I'm Son!"
}
trait Daughter extends Parent {
override def sayHello: String = "Hello! I'm Daughter!"
}
def sayHello[A <: Parent](a: A): Unit = println(a.sayHello)
sayHello(new Son {})
sayHello(new Daughter {})
implicit val string: String = "Hello"
implicit val boolean: Boolean = true
implicit val int: Int = 0
def getImplicitT[T](implicit t: T): T = t
getImplicitT[Int]
getImplicitT[String]
getImplicitT[Boolean]
type Id[A] = A
def getImplicitlyT[T : Id]: T = implicitly[Id[T]]
getImplicitlyT[Int]
getImplicitlyT[String]
getImplicitlyT[Boolean]
Advertisement