mogli
mogli

Reputation: 1609

implicit apply method in scala class

I am learning scala implicits. In below sample code, implicit apply is not getting invoked automatically :

package learn

object ImplicitApplyInClass {

  def main(args: Array[String]): Unit = {


    implicit val ss = "abc"

    //This is working
    val a = A(1).apply.toUpperCase

    //This is giving compile time error
    //val b = A(1).toUpperCase
  }
}

case class A(id: Int) {
  implicit def apply(implicit s: String) = {
    s.toUpperCase    
  }
}

Kindly suggest why apply is not getting invoked implicitly, when the implicit parameter is available in thr scope?

Upvotes: 0

Views: 2434

Answers (3)

Alexey Romanov
Alexey Romanov

Reputation: 170733

When you define an implicit method inside class A this isn't at all the same as defining an implicit conversion from this class.

It's usable as an implicit in the scope where it's defined, but it's an implicit conversion from String to String, which the compiler won't have any reason to use implicitly.

Upvotes: 0

蘇哲聖
蘇哲聖

Reputation: 795

You can try this:

object ImplicitApplyInClass {
  def main(args: Array[String]): Unit = {
    implicit val ss = "abc"
    val b = A(1).toUpperCase
    println(b)
  }
}
object A {
  implicit def f(a: A)(implicit s: String): String = s
}
case class A(id: Int)

Upvotes: 0

Dmytro Mitin
Dmytro Mitin

Reputation: 51658

You can add empty parameter list and this will work:

  case class A(id: Int) {
    implicit def apply()(implicit s: String) = {
      s.toUpperCase
    }
  }

  val b = A(1)().toUpperCase
  println(b) // ABC

Here apply works not as an implicit conversion.

An implicit conversion from type S to type T is defined by an implicit value which has function type S => T, or by an implicit method convertible to a value of that type.

Implicit conversions are applied in two situations:

• If an expression e is of type S, and S does not conform to the expression’s expected type T.

• In a selection e.m with e of type S, if the selector m does not denote a member of S.

In the first case, a conversion c is searched for which is applicable to e and whose result type conforms to T. In the second case, a conversion c is searched for which is applicable to e and whose result contains a member named m.

From here.

In your code it's none of the cases.

Case 1 is not applicable since apply is String => String. Case 2 is not applicable since there is no implicit conversion A => { def toUpperCase }.

Upvotes: 2

Related Questions