I want to have a flexible generator for case class.
case class ABC(a: String, b: String, c: String)
val genAbc = (new Gen).withB("b").withA("a").withC("c")
(new Gen).withA("a").toAbc //<- error
There is a type-safe version of the builder pattern in Scala, see http://blog.rafaelferreira.net/2008/07/type-safe-builder-pattern-in-scala.html
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.