Kevin Schmidt
Kevin Schmidt

Reputation: 2251

implict conversion to StringOps not applied within a implict val function body

In the following code snippet (using scala 2.10.3) TestClass1 does not compile with error "value toInt is not a member of String" but TestClass2 compiles fine:

trait TestTrait {
  implicit def test: (String => Int)
}

object TestClass1 extends TestTrait {
  implicit val test = (value: String) => value.toInt
}

object TestClass2 extends TestTrait {
  implicit def test = (value: String) => value.toInt
}

The StringOps implicit conversion via augmentString(), which provides the toInt function, is not applied in TestClass1 but is applied fine in TestClass2. Can somebody tell me why this is the case and how to keep test a val instead of a def?

Upvotes: 3

Views: 373

Answers (1)

0__
0__

Reputation: 67330

This is a limitation of implicit definitions when the return type needs to inferred, I think. You are in a somewhat similar situation as defining a recursive method. That is to say, the "open" implicit definition triggers implicit lookup in its body, which in theory could be recursive. (At least that's my explanation of this limitation).

You can either annotate the type:

object TestClass1 extends TestTrait {
  implicit val test: String => Int = value => value.toInt  // or _.toInt
}

or remove the implicit keyword—since it is implementing the implicit method from TestTrait, you do not need to re-state the implicit keyword:

object TestClass1 extends TestTrait {
  val test = (value: String) => value.toInt
}

Upvotes: 2

Related Questions