Skip to content

Instantly share code, notes, and snippets.

@torgeir
Last active December 21, 2015 03:48
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save torgeir/6244386 to your computer and use it in GitHub Desktop.
Type safe scala builder, with required arguments, without a build()!
object BuilderTest {
class NAME_WAS_SET
case class Person(name: String, age: Option[Int])
case class PersonBuilder[NAME_NOT_SET](name: Option[String], age: Option[Int]) {
def withName(name: String) = new PersonBuilder[NAME_WAS_SET](Some(name), age)
def withAge(age: Int) = new PersonBuilder[NAME_NOT_SET](name, Some(age))
}
object PersonBuilder {
def apply() = new PersonBuilder(None, None)
implicit def builder2Instance(builder: PersonBuilder[NAME_WAS_SET]) = new Person(builder.name.get, builder.age)
}
def main(args: Array[String]) {
val p1: Person = PersonBuilder() withName("Torgeir") withAge(29)
val p2: Person = PersonBuilder() withAge(29) withName("Torgeir")
val p3: Person = PersonBuilder() withName("Torgeir")
// val p4: Person = PersonBuilder() withAge(29) // does not compile
println(p1, p2, p3) // (Person(Torgeir,Some(29)),Person(Torgeir,Some(29)),Person(Torgeir,None))
}
}
@nilsga
Copy link

nilsga commented Feb 23, 2015

object BuilderTest {

  class NAME_WAS_SET

  case class Person(name: String, age: Option[Int])

  case class PersonBuilder[T](name: Option[String], age: Option[Int]) {
    def withName(name: String) = new PersonBuilder[NAME_WAS_SET](Some(name), age)
    def withAge(age: Int)      = new PersonBuilder[T](name, Some(age))
  }

  object PersonBuilder {
    def apply() = new PersonBuilder(None, None)
    implicit def builder2Instance(builder: PersonBuilder[NAME_WAS_SET]) = new Person(builder.name.get, builder.age)
  }

  def main(args: Array[String]) {
    val p1: Person = PersonBuilder() withName("Torgeir") withAge(29)
    val p2: Person = PersonBuilder() withAge(29) withName("Torgeir")
    val p3: Person = PersonBuilder() withName("Torgeir")
    // val p4: Person = PersonBuilder() withAge(29) // does not compile

    println(p1, p2, p3) // (Person(Torgeir,Some(29)),Person(Torgeir,Some(29)),Person(Torgeir,None))
  }
}

Blir det ekvivalent?

@torgeir
Copy link
Author

torgeir commented Feb 23, 2015

Yess!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment