scala/ScalaBook/chapter-12/src/main/scala/scalabook/ep/family/oc/base.scala
package scalabook.ep.family.oc
/**
* Family-based functional (operation-centric) decomposition.
*
* @author Christos KK Loverdos
*/
trait BaseLang {
type Operation <: BaseOp
trait BaseD {
def perform(op: Operation)
}
trait BaseOp {
def computeNumD(data: NumD)
}
class NumD(val value: Int) extends BaseD {
def perform(op: Operation) {
op.computeNumD(this)
}
}
class EvalOp extends BaseOp { this: Operation =>
var result: Option[Int] = None
def apply(data: BaseD) = {
data.perform(this) // the self-type is needed for the call
result.get
}
def computeNumD(data: NumD) {
this.result = Some(data.value)
}
}
def newEvalOp(): EvalOp with Operation
object eval {
def apply(data: BaseD) = newEvalOp()(data)
}
}
object FixBaseLang extends BaseLang {
type Operation = BaseOp
def newEvalOp() = new EvalOp // Operation is fixed now
}