4

Possible Duplicate:
How can I chain implicits in Scala?

Can Scala apply multiple implicit conversions in one expression?

Consider this simple example:

  case class Wrapper(s: String)

  case class WrapperWrapper(w: Wrapper)

  implicit def string2Wrapper(s: String) = Wrapper(s)

  implicit def wrapper2WrapperWrapper(w: Wrapper) = WrapperWrapper(w)

  // implicit conversation -->  w = string2Wrapper("w")
  val w: Wrapper = "w"

  // implicit conversation -->  ww = wrapper2WrapperWrapper(w)
  val ww: WrapperWrapper = w

  // does NOT compile!
  // ideally --> sad = wrapper2WrapperWrapper(string2Wrapper("ww"))
  val sad: WrapperWrapper = "ww"

Is there any way to get the "double" conversion in the last line to work?

I can help things along by defining another implicit like:

implicit def string2WrapperWrapper(s:String) = wrapper2WrapperWrapper(s)

but it seems like that shouldn't be necessary...

Community
  • 1
  • 1
Brian Kent
  • 3,754
  • 1
  • 26
  • 31

2 Answers2

6

I'm afraid I don't have a concise reference to hand (the answer is scattered through 6.26 and chapter 7 of The Scala Language Specification), but the answer is no.

This is due to practicality - double implicit conversions would square the number of possible conversions available, greatly increasing the chance of collisions and making it harder to work out exactly what would happen with a given conversion.

It's not ideal that you have to declare the String to WrapperWrapper conversion yourself; but given how rarely you need to do this in practice, compared to the potential confusion of double implicits, I do consider it the lesser of two evils.

Andrzej Doyle
  • 102,507
  • 33
  • 189
  • 228
5

You can coerce the sequence of conversions fairly concisely:

scala>   val sad: WrapperWrapper = ("ww": Wrapper)           
sad: WrapperWrapper = WrapperWrapper(Wrapper(ww))

As explained by @Andrzej Doyle, two conversions at a time magnifies the risk of accidental conversions happening and so it is dissallowed.

Don Mackenzie
  • 7,953
  • 7
  • 31
  • 32