I am using phantom types in the type-safe builder pattern to ensure methods are called only once as in the following code sample
sealed trait TBoolean
sealed trait TTrue extends TBoolean
sealed trait TFalse extends TBoolean
class Builder[MethodCalled <: TBoolean] private() {
def foo()(implicit ev: MethodCalled =:= TFalse): Builder[TTrue] = {
new Builder[TTrue]
}
}
object Builder {
def apply() = new Builder[TFalse]()
}
I really appreciate this approach since one can use the .
-operator to chain method calls (unlike with other approaches)
However, this becomes unhandy if there are many methods to guard ending with something like
class Builder[MethodCalled1 <: TBoolean, MethodCalled2 <: TBoolean, ... ,MethodCalledN <: TBoolean]
Is there a way to create a "type struct"? Something like the following pseudo code:
type S {
type MethodCalled1 <: TBoolean
type MethodCalled2 <: TBoolean
...
type MethodCalledN <: TBoolean
}
class Builder[S] private() {
def foo()(implicit ev: S#MethodCalled1 =:= TFalse): Builder[S#MethodCalled1.TTrue] = {
new Builder[S#MethodCalled1.TTrue]
}
}