2

I have a class A which also defines an implicit conversion to B.

case class A(number:Int) 
case class B(number:Int, tag:String)
implicit def  AtoB(a:A) = B(a.number,"Hello World")

I also have a function that retrieves A and would like to invoke a function that takes as argument implicit B:

def hello()(implicit b:B)= {....}
def execute = {
    implicit val a:A  = ....
    hello()  //doesnt compile missing implicit parameter b
}

How can I get this code to work without explicitly defining B? i.e

val b:B = a
jub0bs
  • 60,866
  • 25
  • 183
  • 186
David H
  • 1,346
  • 3
  • 16
  • 29
  • 1
    The only thing you can do is `hello()(a)` or create another function. scala by design doesn't allow 'chains' of implicits. – yw3410 Feb 29 '16 at 14:03
  • That is not completely correct. If you call a method with an implicit parameter of the same type as an implicit parameter given to the method you're currently in, it will be passed through. – Nabil A. Feb 29 '16 at 14:29

1 Answers1

4

Define a function like this:

implicit def implicitBfromA(implicit a: A): B = a

And either have it in scope when you call hello, or put it into the companion object of B.

This function is not an implicit conversion. It states, that there is an implicit value of type B available, if there is already an implicit value of type A available in the scope.

Note that it for it to work, it should either be defined after AtoB in the file, or AtoB should have an explicitly specified return type: implicit def AtoB(a:A): B = B(a.number, "Hello World"), or you should explicitly call AtoB in its body: implicit def implicitBfromA(implicit a: A): B = AtoB(a)

A full working example:

case class A(number: Int)

case class B(number: Int, tag: String)
object B {
  implicit def implicitB(implicit a: A): B = a
}

implicit def AtoB(a:A): B = B(a.number, "Hello World")

def hello()(implicit b: B) = b.number.toString + b.tag

def execute = {
  implicit val a: A = A(10)
  hello()
}
Kolmar
  • 14,086
  • 1
  • 22
  • 25