1

I found an interesting scala implementation of Builder pattern, but I can't understand what a few lines mean:

  case class Built(a:Int, b:String){}
  trait Status
  trait Done extends Status
  trait Need extends Status

  class Builder[A<:Status,B<:Status] private(){
      private var built = Built(0,"")
      def setA(a0:Int)={
        built = built.copy(a=a0)
        this.asInstanceOf[Builder[Done,B]] 
      }
      def setB(b0: String) = { 
          built = built.copy(b = b0) 
          this.asInstanceOf[Builder[A,Done]] 
      }
     def result(implicit ev: Builder[A,B] <:< Builder[Done,Done]) = built 
  }

  object Builder{
    def apply() =  new Builder[Need,Need]
  }

1) What does private() mean in class Builder[A<:Status,B<:Status] private() class declaration?

2) What is the meaning of implicit ev: Builder[A,B] <:< Builder[Done,Done] in result function?

Daenyth
  • 35,856
  • 13
  • 85
  • 124
danny.lesnik
  • 18,479
  • 29
  • 135
  • 200

2 Answers2

5

1)

The private means that the primary constructor for Builder can not be accessed from outside.

Since there are no other constructors, the only way to get an instance is through the companion object with the apply method.

Example:

val builder = Builder()

2)

You have methods in Builder to set both parameters for the Built case-class. The method result gives you the constructed Built-instance. The evidence makes sure that you have set both parameters and will not allow you to create an instance if you didn't do it.

Example (I did not test this, so please correct me if I am wrong):

val builderA = Builder().setA(3)
val resultA = builderA.result //should not compile because this is Builder[Done, Need]
val builderAB = builderA.setB("hello") //now this is Builder[Done, Done]
val resultAB = builderAB.result //should compile and yield Built(3, "hello")
Gábor Bakos
  • 8,982
  • 52
  • 35
  • 52
Kigyo
  • 5,668
  • 1
  • 20
  • 24
  • 1
    Your second explanation is wrong. There is no Exception in the second line, it just do not compile, because it cannot prove the type is `Builder[Done, Done]`. – Gábor Bakos Jun 06 '14 at 19:53
  • Ah, thats what I meant. Thanks. – Kigyo Jun 06 '14 at 19:54
  • Thanks, but what what does <:< mean? Is it used only in Implicit parameters? – danny.lesnik Jun 06 '14 at 19:59
  • 1
    `A <:< B` means: A has to be a sub-type of B. So far I have only seen it for implicit evidence. Some more detailed answers: http://stackoverflow.com/questions/2603003/operator-in-scala http://stackoverflow.com/questions/3427345/what-do-and-mean-in-scala-2-8-and-where-are-they-documented – Kigyo Jun 06 '14 at 20:07
1

For your first question, the keyword private in this position means the constructor for the class is private.

Jason Oviedo
  • 459
  • 1
  • 5
  • 16