-1

As per the accepted answer in thread Using implicit objects within classes

if implicit objects are encapsulated within companion object of a generic type then there is no need to explicitly import properties and behaviour from object.

With that logic I am not able to understand why is below code not getting compiled after removing import num._

implicit class GenericMedian[T: Numeric](seq: Seq[T]) {
    def median(): Double = {
      val num: Numeric[T] = implicitly[Numeric[T]]

      import num._
      val medianPosition = seq.length / 2
      seq.sortWith(gt) match {
        case x if x.length % 2 != 0 => x(medianPosition).toDouble()
        case x => (x(medianPosition).toDouble() + x(medianPosition - 1).toDouble()) / 2
      }

    }
  }

Can someone throw some light on this concept?

Hitesh
  • 432
  • 3
  • 13

1 Answers1

1

Because uses of gt and toDouble that are imported from the num are not in the implicit position - i.e. toDouble is used explicitly and sortWith argument is not marked as implicit - so implicit resolution will not work for them.

So, the import num._ basically puts into explicit scope methods used later, specifically num.gt and another implicit Numeric[T].Ops which has toDouble implementation.

Consider the following example - median is rewritten to replace those two explicit uses with calls to functions that use implicit resolution:

implicit class GenericMedian[T: Numeric](seq: Seq[T]) {
  def median(): Double = {
    val medianPosition = seq.length / 2
    sortWithImpl(seq) match {
      case x if x.length % 2 != 0 => makeDouble(x(medianPosition))
      case x => (
        makeDouble(x(medianPosition)) +
        makeDouble(x(medianPosition - 1))
      ) / 2
    }

  }
  private def makeDouble(t: T)(implicit numeric: Numeric[T]): Double = numeric.toDouble(t)

  private def sortWithImplicit(seq: Seq[T])(implicit numeric: Numeric[T]): Seq[T] = seq.sortWith(numeric.gt)
}

Note that no numeric instance is conjured from implicit scope makeDouble and sortWithImplicit use implicit resolution.

For deeper understanding, consider consulting with scala docs on implicits or this answer (in particular, "Accessing an Implicit Parameter Introduced by a Context Bound" section)

J0HN
  • 26,063
  • 5
  • 54
  • 85