chessman chessman - 1 year ago 86
Scala Question

Setters for case class in Scala

I want to have a flexible generator for case class.

case class ABC(a: String, b: String, c: String)

I want to write in any order:

val genAbc = (new Gen).withB("b").withA("a").withC("c")

And be able to convert it to case class if all parameters are set:


If not all parameters are set, I want to get compile error:

(new Gen).withA("a").toAbc //<- error

Is it possible?

Answer Source

There is a type-safe version of the builder pattern in Scala, see

But, if you're willing to give up the requirement to be able to set the parameters in any order, there is a much simpler way:

scala> val abcBuilder = (Abc.apply _).curried
abcBuilder: String => (String => (String => Abc)) = <function1>

That creates a curried function using the Abc class's smart constructor (Abc.apply). A curried function lets you pass in each argument separately. In the interim you keep getting back more functions which take one argument and get you one step closer to an Abc instance. So:

scala> abcBuilder("a")
res11: String => (String => Abc) = <function1>

scala> res11("b")
res12: String => Abc = <function1>

scala> res12("c")
res13: Abc = Abc(a,b,c)

This is all also type-safe (to the extent that you use distinct types for the parameters); so e.g. abcBuilder(1) would give you a compile error.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download