scala/ScalaBook/chapter-12/src/main/scala/scalabook/ep/ocgenselfp/sub/sub.scala

package scalabook.ep.ocgenselfp.sub
/**
 * Operation-centric approach with generics and Torgersen's self parameter
 * trick.
 *
 * Here we define more data (apart from the existing NumD) in a statically type-safe
 * manner.
 * 
 * @author Christos KK Loverdos
 */

// The new operation is easy
trait PlusOp extends EvalOp {
    def computePlusD[V <: PlusOp](data: PlusD[V], self: V)
}

// The new data is easy
class PlusD[V <: PlusOp](val a: BaseD[V], val b: BaseD[V]) extends BaseD[V] {
    def perform(op: V) {
        op.computePlusD(this, op)
    }
}

// And this is the concrete implementation of the new operation
// as a subclass of the previously defined (in ../base.scala)
// EvalOp.
class PlusEvalOp extends EvalOp with PlusOp {
    def computePlusD[V <: PlusOp](data: PlusD[V], self: V) = {
        val ia: Int = eval(data.a, self)
        val ib: Int = eval(data.b, self)
        this.result = Some(ia + ib)
    }
}