jhegedus
jhegedus

Reputation: 20653

Implicit parameters cannot be found when imported (from an Object)

Why can not the code below find the imported implicits from MyProducers? In my understanding this should work fine because the implicits are in scope.

Error:(16, 34) could not find implicit value for evidence parameter of type MyProducers.ListProducer[Int]
  val stuffInt:Int = getHead[Int]()
Error:(16, 34) not enough arguments for method getHead: (implicit evidence$2: MyProducers.ListProducer[Int])Int.
Unspecified value parameter evidence$2.
  val stuffInt:Int = getHead[Int]()
Error:(18, 43) could not find implicit value for evidence parameter of type MyProducers.ListProducer[String]
  val stuffString:String = getHead[String]()
Error:(18, 43) not enough arguments for method getHead: (implicit evidence$2: MyProducers.ListProducer[String])String.
Unspecified value parameter evidence$2.
  val stuffString:String = getHead[String]()

Code:

object Resolver {

  import MyProducers._
  import MyProducers._

  def getList[T:ListProducer]():List[T]= implicitly[ListProducer[T]].produceList


  def getHead[T:ListProducer]():T= getList[T]().head

  val stuffInt:Int = getHead[Int]()

  val stuffString:String = getHead[String]()

  val im=ip  // this compiles fine, so implicits are in scope
  val sm=sp
}

object MyProducers{
  trait ListProducer[T]{
    def produceList:List[T]
  }
  object IntProducer extends ListProducer[Int]{
    override def produceList = List(22, 42)
  }
  implicit val ip=IntProducer

  object StringProducer extends ListProducer[String]{
    override def produceList = List("stuff", "Shiraly")
  }
  implicit val sp=StringProducer
}

What is strange, that this code compiles fine:

object Resolver {

  import MyProducers._
  import MyProducers._
  trait ListProducer[T]{
    def produceList:List[T]
  }
  object IntProducer extends ListProducer[Int]{
    override def produceList = List(22, 42)
  }
  implicit val ip=IntProducer

  object StringProducer extends ListProducer[String]{
    override def produceList = List("stuff", "Shiraly")
  }
  implicit val sp=StringProducer


  def getList[T:ListProducer]():List[T]= implicitly[ListProducer[T]].produceList


  def getHead[T:ListProducer]():T= getList[T]().head

  val stuffInt:Int = getHead[Int]()

  val stuffString:String = getHead[String]()

  val im=ip
  val sm=sp
}

Any idea why the first code does not compile while the second does ?

Upvotes: 1

Views: 535

Answers (1)

Daenyth
Daenyth

Reputation: 37461

Implicit vals and defs need to have type annotations on them. Add those, and the implicits will be found.

Upvotes: 4

Related Questions