scala/ScalaBook/chapter-12/src/main/scala/scalabook/ep/ocgenerr/base.scala

package scalabook.ep.ocgenerr

/**
 * Definitions for an Operation-Centric approach with generics.
 *
 * Note that this will not compile, since the type of this (in EvalOp)
 * is not the needed type V.
 *
 * So we have this example commented, in order for the whole project to
 * compile properly.
 *
 * See package scalabook.ep.ocgenselfp for an approach to this problem.
 *  
 * @author Christos KK Loverdos
 */

// Since in the op-centric approach we have a problem with new data,
// we parameterize them with the operation to be performed.
trait BaseD[V <: BaseOp] {
  def perform(op: V)
}

// A concrete implementation of data
class NumD[V <: BaseOp](val value: Int) extends BaseD[V] {
  def perform(op: V) {
    op.computeNumD(this)
  }
}

// The base definition of our operation.
// 
trait BaseOp {
  def computeNumD[V <: BaseOp](data: NumD[V])
}

class EvalOp extends BaseOp {
  var result: Option[Int] = None

  def apply[V <: BaseOp](data: BaseD[V]) = {
    // This will not type check, giving the error:
    ////////////////////////////////////////////////////////////
    // type mismatch;
    //  found   : EvalOp
    //  required: V
    //     data.perform(this)
    //                  ^
    ////////////////////////////////////////////////////////////
    // So we have to use comments :(
    /*data.perform(this)*/
    result.get
  }


    def computeNumD[V <: BaseOp](data: NumD[V]) {
      this.result = Some(data.value)
    }
}