3
votes

As I write programs in Scala with case classes, I've encountered a recurring pattern where I would want to put a creator of a case class as a parameter to it for future reference. I've learnt that we can capture this pattern by putting implicit value to a case class

abstract class MessageCreator
case class SomeMessage(s:String)(implicit val creator:MessageCreator)
class MyCreator extends MessageCreator { implicit val creator = this}
class ACreator extends MyCreator { def newMessage = SomeMessage("hello") }

Then, newMessage here will have member creator that refers to an instance of ACreator itself.

Now, I have a bunch of case classes that would do the same thing. My question is, how would you repeat this pattern without having to copy and paste (implicit val creator:MessageCreator) every time I want to define such case class?

I have tried defining an abstract class with implicit val, then inherit them from case class, but Scala was complaining that the implicit val from abstract class was not defined in the case class. Obviously, case class cannot be inherited.

If this cannot be done programmatically, I might start looking into writing a macro (which would be a fine solution). I want to make sure that I am not missing anything here.

1
IMHO this kind of parameters should be passed explicitly and only explicitly. If you really need this you can use companion objects as factories to pass creator parameter.vitalii
Thanks for the comment. If I have a companion object with, say def apply(implicit val creator:MessageCreator) {...}, how do I make case classes inherit such class with companion object?In-Ho Yi

1 Answers

1
votes

Without knowing more about it the domain I'd ask some questions along the lines of:

  1. Why can't your factory be your companion object? For a case class this already is explicitly so due to the language and it's compiler. If you need another I'd overload the apply.

  2. Why does your class need the ability to create more of itself? Isn't that partially what "copy" is for (and by partial I mean without all fields replaced.)

The season I'd ask these questions is that, devoid of context, it sounds like you've introduced additional complexity without much benefit.

Finally if you're implicitly passing state I'd caution you against it. This can lead to all sorts of issues and problems down the line. Implicits are wonderful unless they cause a bug, in which case that bug becomes difficult to decipher and track down. I'd almost go so far as to say you should only use implicit for type classes