Implicit conversion method in companion object needs to be imported? Contradiction with "Scala for the impatient" book

StackOverflow https://stackoverflow.com/questions/22252530

  •  11-06-2023
  •  | 
  •  

Question

The code below does not work but it should according to the "Scala for the impatient" book (please see excerpt below). So what do I not understand here ? Did the rules for implicit conversion change in recent versions of Scala (2.8 vs. 2.10) ?

EDIT:

After looking at this question I realised that b.hello needs to be changed to (b:A).hello. That is not very implicit. Is there any way around this?

EDIT 2:

After reading some more this it seems that there is no other way than import.

object A {
  implicit def b2a(b:B)=new A
}
class A{
  def hello=println("hello")
}
class B 

object ImplicitConversion extends App{
  val b=new B
  b.hello
}

enter image description here

Was it helpful?

Solution

That's because the Scala compiler has no way how to figure out that you want to convert a B to an A just by looking at this piece of code:

val b = new B
b.hello // I know the source type is B, but what's the target type?

Consider the case where there's a C similar to your A. Which of the two conversions should Scala choose? It's too much to ask Scala to search all the other companion objects in the system for a possible implicit conversion from the, already known, source type. And it's quite possible that it'll end up with an ambiguous result.

The easiest solution in your case is to move the B to A conversion from the companion object of A to the companion object of B.

class A {
  def hello=println("hello")
}

class B 

object B {
  implicit def b2a(b:B)=new A
}

object ImplicitConversion extends App {
  val b=new B
  b.hello
}

OTHER TIPS

The solution proposed by Stan is satisfactory because:

object B  {
  implicit def b2a(b:B)=new A 
}

class A{
  def hello=println("hello")
}

class B 

class C extends B


object ImplicitConversion extends App{

  val c=new C
  c.hello

}

Here I only need to include the implicit conversion b2a in B's companion object.

Then I can use all subclasses of B as A.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top