Domanda

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: Int): T
    def minus(x: T, y: T): T
  }
  object NumberLike {
    implicit object NumberLikeDouble extends NumberLike[Double] {
      def plus(x: Double, y: Double): Double = x + y
      def divide(x: Double, y: Int): Double = x / y
      def minus(x: Double, y: Double): Double = x - y
    }
    implicit object NumberLikeInt extends NumberLike[Int] {
      def plus(x: Int, y: Int): Int = x + y
      def divide(x: Int, y: Int): Int = x / y
      def minus(x: Int, y: Int): Int = x - y
    }
  }
}

What are they? Where are they described? I only found definition of implicit classes on the web but not of implicit objects.

È stato utile?

Soluzione

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

Altri suggerimenti

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top