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

package scalabook.ep.dcgen

/**
 * Data-Centric approach with generics (& f-bounds)
 * 
 * @author Christos KK Loverdos
 */

// The base data
trait BaseD[T <: BaseD[T]] {
    def eval: Int
}

// 1st concrete implementation
class NumD[T <: BaseD[T]](value: Int) extends BaseD[T] {
    def eval = value
}

// 2nd concrete implementation
class PlusD[T <: BaseD[T]](a: T, b: T) extends BaseD[T] {
    def eval = a.eval + b.eval
}

// Time to add an extension in the difficult dimension of operations.
trait ReprD[T <: ReprD[T]] extends BaseD[T] {
    def repr: String
}

// 1st concrete implementation of the extension
class ReprNumD[T <: ReprD[T]](value: Int) extends NumD[T](value) with ReprD[T] {
    def repr = value.toString
}

// 1st concrete implementation of the extension
class ReprPlusD[T <: ReprD[T]](a: T, b: T) extends PlusD[T](a, b) with ReprD[T] {
    def repr = a.repr + " + " + b.repr
}

// fixed-point versions (the F-bound are fixed)
trait FBaseD extends BaseD[FBaseD]
trait FReprD extends ReprD[FReprD]
class FReprNumD(value: Int) extends ReprNumD[FReprD](value)
class FReprPlusD(a: FReprD, b: FReprD) extends ReprPlusD[FReprD](a, b)