In our previous blog, The Magic of Implicit, we have talked about how implicit values are being used. In this blog, we will explore Type Conversion with implicit and implicit classes.

Let’s start with a simple example,


scala> val i: Int = 2.3
<console>:11: error: type mismatch;
 found   : Double(2.3)
 required: Int
       val i: Int = 2.3

Here we were trying to assign a double type value to an Int type variable. That’s why Scala Compiler throws an error saying type mismatch. So what to do when the compiler is not able to do automatic conversions. Here implicit methods come into the picture to solve the type conversion.

The Implicit function gives us the facility to define conversion between types. 

To define an implicit method, just put an implicit before def. And when we define it, Scala Compiler throws a warning to import implicit conversions. Let’s create an implicit method which takes a double value and return an int value.


scala> import scala.language.implicitConversions
import scala.language.implicitConversions

scala> implicit def doubleToInt(x: Double) = x.toInt
doubleToInt: (x: Double)Int

scala> val i: Int = 2.3
i: Int = 2

Notice, when we assigned again double value where int value is expected. Scala Compiler then tries to find an implicit function in current scope that can provide the expected type. Earlier there is no implicit method so Scala Compiler threw an error. But this time it finds an implicit method which takes a Double value and produces Int value.

Recently I was working with Scala List and I was hoping if Scala could provide a mean method to List class. Scala 2.10 provides implicit classes which help us to extend the functionality of the existing library.

An implicit class is a type of class that provides an automatic conversion from another class

We can define an implicit class similarly the way we defined implicit methods but according to SIP-13, Implicit Classes, “An implicit class must be defined in a scope where method definitions are allowed (not at the top level).

So, we need to fulfill the requirement to class to be implicit:

  1.  It must be defined in an object, class, trait and package object.
  2. An implicit class must have a primary constructor exactly with one argument. It may also include an additional implicit parameters list.
  3. The implicit class name must not conflict with another object or trait in the current namespace. Thus, a case class could not be used as an implicit class because
    its automatically generated companion object would break this rule

For example, we want to provide a mean method to list.


scala> val list = List(1 to 10: _*)
list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> :paste
// Entering paste mode (ctrl-D to finish)

object Helper {
  implicit class ListOps(list: List[Int]) {
    def mean: Int = list.sum / list.size
  }
}

// Exiting paste mode, now interpreting.

defined object Helper

scala> import Helper._
import Helper._

scala> list.mean
res5: Int = 5

How does this work?

The Scala compiler uses implicit conversions when it finds an unknown method or field being accessed on an instance. It checks in the current scope for implicit conversions. If it finds a match for missing field or method, it will add an automatic conversion to the implicit class, supporting the field or method access on the implicit type. If a match is not found, Scala Compiler will throw an error for invoking unknown fields or methods.

This is popular Pimp My Library pattern used in Scala to extend the functionality of pre-existing classes.

So, we have seen how implicit methods allow type conversion and implicit classes give us the facility to extend or add functionality to existing libraries. We will explore more about simplicity in future blogs. Till then stay tuned 🙂

Please feel free to suggest and comment.

References:

  1. SIP-13 – Implicit classes
  2. Pimp my Library

knoldus-advt-sticker

2 comments

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s