Search code examples
scalainheritanceimplicittraits

how to map implicit class parameter to trait variable?


I face interesting problem with implicit parameters and tratis.

I have an abstract class Parent accepting one integer and 2 other params implicitely:

abstract class Parent(a: Int)(implicit str: String, map: Map[String,String]) {/*...*/}

and a trait ClassTrait that will be mixed with Parent and uses the implicits:

trait ClassTrait {
    val str: String
    val map: Map[String,String]

    def doSth() = str.length
}

so now I want to make sth like this (withnout keyword abstract):

class Child(a: Int)(implicit str: String, map: Map[String,String]) extends Parent(a) with ClassTrait {
    def doSth2 = doSth * 10
}

What syntax should I use to map the implicit params to trait vals? Compiler returns this error:

foo.scala:10: error: class Child needs to be abstract, since:
value map in trait ClassTrait of type Map[String,String] is not defined
value str in trait ClassTrait of type String is not defined
class Child(a: Int)(implicit str: String, map: Map[String,String]) extends Parent(a) with ClassTrait {
      ^
one error found

In complex example, I use implicit parameters in the trait but since traits can't have any params (have no constructor), I need to declare used implicits again.

Thanks for help.


Solution

  • Try

    class Child(a: Int)(implicit val str: String, map: Map[String,String]) extends Parent(a) with ClassTrait {
       def doSth2 = doSth * 10
     }
    

    (See the val I added)

    Or use case class. Then they will be fields.

    Alternative way could be to not make them implicit and use an apply method in a companion object that takes implicits to set them. But you still need to make them fields, your current code is technically just treating them as constructor args.