I was reading about type classes where implicit objects were mentioned:
object Math {
trait NumberLike[T] {
def plus(x: T, y: T): T
def divide(x: T, y:
In Scala, objects and values are treated mostly the same. An implicit object can be thought of as a value which is found in the process of looking up an implicit of its type.
In your example, if one implicitly looks for a NumberLike
type class with type parameter Double
or Int
, one will find NumberLikeDouble
and NumberLikeInt
.
implicit object NumberLikeDouble extends NumberLike[Double]
is thus roughly the same as
implicit val NumberLikeDouble: NumberLike[Double] = new NumberLike[Double] { ...}
or
implicit def NumberLikeDouble: NumberLike[Double] = new NumberLike[Double] { ...}
Like a val
, there is only a single value of that type and instantiation is not needed.
A simple use case:
import Math.NumberLike
def sum[A](x: A, y: A)(implicit nl: NumberLike[A]) = nl.plus(x, y)
sum(4, 5) // finds NumberLikeInt
Thanks to implicit objects, you can define:
def mymethod[T : NumberLike](value: T): T = {
implicitly[NumberLike[T]].plus(value, value)
}
which allows you to call your methods on Double and Floats because you have objects to deal with them.
scala> mymethod(1.0)
res0: Double = 2.0
scala> mymethod(2)
res0: Int = 4
scala> mymethod("test") //Error