我想检查不同的方式来扩展这个代码,然后在需要时混合这些功能扩展。
// Initial object algebra interface for expressions: integers and addition
trait ExpAlg[E] {
def lit(x : Int) : E
def add(e1 : E, e2 : E) : E
}
// An object algebra implementing that interface (evaluation)
// The evaluation interface
trait Eval {
def eval() : Int
}
// The object algebra
trait EvalExpAlg extends ExpAlg[Eval] {
def lit(x : Int) = new Eval() {
def eval() = x
}
def add(e1 : Eval, e2 : Eval) = new Eval() {
def eval() = e1.eval() + e2.eval()
}
}
// Evolution 1: Adding subtraction
trait SubExpAlg[E] extends ExpAlg[E] {
def sub(e1 : E, e2 : E) : E
}
// Updating evaluation:
trait EvalSubExpAlg extends EvalExpAlg with SubExpAlg[Eval] {
def sub(e1 : Eval, e2 : Eval) = new Eval() {
def eval() = e1.eval() - e2.eval()
}
}
// Evolution 2: Adding pretty printing
trait PPrint {
def print() : String
}
trait PrintExpAlg extends ExpAlg[PPrint] {
def lit(x: Int) = new PPrint() {
def print() = x.toString()
}
def add(e1: PPrint, e2: PPrint) = new PPrint() {
def print() = e1.print() + "+" + e2.print()
}
}
trait PrintSubExpAlg extends PrintExpAlg with SubExpAlg[PPrint] {
def sub(e1: PPrint, e2: PPrint) = new PPrint() {
def print() = e1.print() + "-" + e2.print()
}
}
object OA extends App {
trait Test extends EvalSubExpAlg with PrintSubExpAlg //error
}
目前我遇到了一个错误,提示说:
"illegal inheritance; trait Test inherits different type instances of trait SubExpAlg: pack.SubExpAlg[pack.PPrint] and pack.SubExpAlg[pack.Eval]"
我该如何将类型Eval和PPint放在“帽子”下,以便被识别为同一家族的类型,而不是错误的解决方案?即使我可能会有两种类型成员之间的冲突继承,在这种情况下是否仍然可以保持兼容性?
编辑
我已经做出了更改,如下所示:
class Operations
// Initial object algebra interface for expressions: integers and addition
trait ExpAlg {
type Opr <: Operations
def lit(x : Int) : Opr
def add(e1 : Opr, e2 : Opr) : Opr
}
// An object algebra implementing that interface (evaluation)
// The evaluation interface
trait Eval extends Operations {
def eval() : Int
}
// The object algebra
trait EvalExpAlg extends ExpAlg {
type Opr = Eval
def lit(x : Int) = new Eval() {
def eval() = x
}
def add(e1 : Eval, e2 : Eval) = new Eval() {
def eval() = e1.eval() + e2.eval()
}
}
// Evolution 1: Adding subtraction
trait SubExpAlg extends ExpAlg {
def sub(e1 : Opr, e2 : Opr) : Opr
}
// Updating evaluation:
trait EvalSubExpAlg extends EvalExpAlg with SubExpAlg {
def sub(e1 : Eval, e2 : Eval) = new Eval() {
def eval() = e1.eval() - e2.eval()
}
}
// Evolution 2: Adding pretty printing
trait PPrint extends Operations {
def print() : String
}
trait PrintExpAlg extends ExpAlg {
type Opr = PPrint
def lit(x: Int) = new PPrint() {
def print() = x.toString()
}
def add(e1: PPrint, e2: PPrint) = new PPrint() {
def print() = e1.print() + "+" + e2.print()
}
}
trait PrintSubExpAlg extends PrintExpAlg with SubExpAlg {
def sub(e1: PPrint, e2: PPrint) = new PPrint() {
def print() = e1.print() + "-" + e2.print()
}
}
object OA extends App {
class Test extends EvalSubExpAlg
class Test2 extends PrintSubExpAlg
val evaluate = new Test
val print = new Test2
val l1 = evaluate.lit(5)
val l2 = evaluate.lit(4)
val add1 = evaluate.add(l1, l2).eval()
val print1 = print.add(print.lit(5), print.lit(4)).print()
println(print1)
println(add1)
}
我唯一要求的可能只是使用一个
Test
类,并且通过引用这些类型来在两种方法之间进行导航。
Test
中写下lit(5)
时,您实际上希望调用哪个方法? - dk14