What is the idiomatic way to extend a class which has implicit parameters in the constructor in Scala?

Viewed 345

I am extending an abstract class which defines an implicit parameter in its constructor.

It seems like there are 3 different ways to do this:

abstract class Base(z: ZType)(implicit a: AType)

// Explicit
class First(z: ZType, a: Atype) extends Base(z)(a)

// Explicitly pass a into the child class which
// implicitly passes it into the parent class
class Second(z: ZType, implicit val a: AType) extends Base(z)

// Implicitly passed into both
class Third(z: ZType)(implicit a: AType) extends Base(z)

Perhaps it depends on how the child class is going to be used. In my case, the child class will not have an implicit AType in scope, so I was leaning toward the second option.

My biggest concern with the second option is that I now have 2 implicits defined for the same type, one in the parent class and one in the child class. Does that have any effect since they will always be the same object? Is the second pattern one I should avoid for any reason?

Basically, is there a "right" pattern here or are all of these acceptable depending on the context of the code they are used in?

1 Answers

Option 3 is the best one if you think any user of Second usually wants to pass a implicitly. They can always go the explicit route, but you just make that a little bit harder, and really explicit. This is good in my opinion, and this is indeed the most common pattern.

Option 1 is the right call if you don't control how Base is defined, and you want your users to always pass a explicitly in every case.

Option 2 is never any good, because you can never pass a implicitly that way and it's just more confusing to read than option 1. Note that the following does not compile.

implicit val a: AType = ???
val z: Type = ???
new Second(z)
Related