scala中问题解的表达式

scala中问题解的表达式,scala,Scala,我是斯卡拉的新手。考虑这篇文章()。本文介绍了Scala中表达式问题()的两种解决方案。第3节介绍了面向对象的解决方案,第4节介绍了功能方法 我试图从第3节中的解决方案构造一个完整的程序。因此,我有下面的代码作为我的scala程序(文件名:“ep.scala”) 请解释如何修复这些错误 我使用的是scala版本2.11.8。据我所知,scala在追溯兼容性方面有一些突破,与当前版本的w.r.t.文章版本不同。我对代码进行了调整,以修复由这些语言差异引起的小问题,但这8个错误(都是相同类型的)仍然

我是斯卡拉的新手。考虑这篇文章()。本文介绍了Scala中表达式问题()的两种解决方案。第3节介绍了面向对象的解决方案,第4节介绍了功能方法

我试图从第3节中的解决方案构造一个完整的程序。因此,我有下面的代码作为我的scala程序(文件名:“ep.scala”)

请解释如何修复这些错误

我使用的是scala版本2.11.8。据我所知,scala在追溯兼容性方面有一些突破,与当前版本的w.r.t.文章版本不同。我对代码进行了调整,以修复由这些语言差异引起的小问题,但这8个错误(都是相同类型的)仍然存在。 尝试像traits那样声明由错误指示的类 没有帮助,因为traits不能有参数“as”字段


注:我不想偏离论文中提出的方法。请仅提供如何在不严重偏离此解决方案的情况下修复代码(如上)的解决方案。

此报告可能已有10多年的历史,当时Scala比现在更具实验性,自那时以来Scala在很多地方都发生了变化。但您仍然可以通过一些修改来实现这一点。要修复的最重要的事情是类的多重继承。我不确定它当时在Scala中到底是如何工作的(这正是这里发生的事情)。假设这段代码曾经运行过,那么继承看起来一定是正确的,即只有一组字段是从公共基类继承的。您仍然可以在Scala中使用特性aka和的多重继承来模拟这一点。您可以尝试这样做:

trait Base {
  type exp <: Exp

  trait Exp {
    def eval: Int
  }


  class Num(val value: Int) extends Exp {
    def eval: Int = value
  }

  type BaseNum = Num
}

trait BasePlus extends Base {

  class Plus(val left: exp, val right: exp) extends Exp {
    def eval: Int = left.eval + right.eval
  }

  type BasePlus = Plus
}

trait BaseNeg extends Base {

  class Neg(val term: exp) extends Exp {
    def eval = -term.eval
  }

  type BaseNeg = Neg
}

trait BasePlusNeg extends BasePlus with BaseNeg

trait Show extends Base {
  type exp <: Exp

  trait Exp extends super.Exp {
    def show: String
  }

  trait NumBehavior extends Exp {
    self: BaseNum =>
    override def show: String = value.toString
  }

  final class Num(v: Int) extends BaseNum(v) with NumBehavior with Exp

}

trait ShowPlusNeg extends BasePlusNeg with Show {

  trait PlusBehavior {
    self: BasePlus =>
    def show = left.show + "+" + right.show;
  }

  final class Plus(l: exp, r: exp) extends BasePlus(l, r) with PlusBehavior with Exp

  trait NegBehavior {
    self: BaseNeg =>
    def show = "-(" + term.show + ")";
  }

  class Neg(t: exp) extends BaseNeg(t) with NegBehavior with Exp

}

trait DblePlusNeg extends BasePlusNeg {
  type exp <: Exp

  trait Exp extends super.Exp {
    def dble: exp
  }

  def Num(v: Int): exp

  def Plus(l: exp, r: exp): exp

  def Neg(t: exp): exp


  trait NumBehavior {
    self: BaseNum =>
    def dble = Num(value * 2)
  }

  final class Num(v: Int) extends BaseNum(v) with NumBehavior with Exp


  trait PlusBehavior {
    self: BasePlus =>
    def dble = Plus(left.dble, right.dble)
  }

  class Plus(l: exp, r: exp) extends BasePlus(l, r) with PlusBehavior with Exp


  trait NegBehavior {
    self: BaseNeg =>
    def dble = Neg(term.dble)
  }

  class Neg(t: exp) extends super.Neg(t) with NegBehavior with Exp

}

trait ShowDblePlusNeg extends ShowPlusNeg with DblePlusNeg {
  type exp <: Exp

  trait Exp extends super[ShowPlusNeg].Exp with super[DblePlusNeg].Exp;

  trait NumBehavior extends super[ShowPlusNeg].NumBehavior with super[DblePlusNeg].NumBehavior {
    self: BaseNum =>
  }

  final class Num(v: Int) extends BaseNum(v)
    with NumBehavior
    with Exp


  trait PlusBehavior extends super[ShowPlusNeg].PlusBehavior with super[DblePlusNeg].PlusBehavior {
    self: BasePlus =>
  }

  final class Plus(l: exp, r: exp) extends BasePlus(l, r)
    with PlusBehavior
    with Exp

  trait NegBehavior extends super[ShowPlusNeg].NegBehavior with super[DblePlusNeg].NegBehavior {
    self: BaseNeg =>
  }

  final class Neg(t: exp) extends BaseNeg(t)
    with NegBehavior
    with Exp

}

trait Equals extends Base {
  type exp <: Exp;

  trait Exp extends super.Exp {
    def eql(other: exp): Boolean;

    def isNum(v: Int): Boolean = false;
  }

  trait NumBehavior extends Exp {
    self: BaseNum =>
    def eql(other: exp): Boolean = other.isNum(value);

    override def isNum(v: Int) = v == value;
  }


  final class Num(v: Int) extends BaseNum(v) with NumBehavior with Exp

}

trait EqualsPlusNeg extends BasePlusNeg with Equals {
  type exp <: Exp;

  trait Exp extends super[BasePlusNeg].Exp
    with super[Equals].Exp {
    def isPlus(l: exp, r: exp): Boolean = false;

    def isNeg(t: exp): Boolean = false;
  }


  final class Num(v: Int) extends BaseNum(v)
    with NumBehavior // effectively super[Equals].NumBehavior
    with Exp


  trait PlusBehavior extends Exp {
    self: BasePlus =>
    def eql(other: exp): Boolean = other.isPlus(left, right);

    override def isPlus(l: exp, r: exp) = (left eql l) && (right eql r)
  }

  final class Plus(l: exp, r: exp) extends BasePlus(l, r) with PlusBehavior with Exp


  trait NegBehavior extends Exp {
    self: BaseNeg =>
    def eql(other: exp): Boolean = other.isNeg(term);

    override def isNeg(t: exp) = term eql t
  }

  final class Neg(t: exp) extends BaseNeg(t) with NegBehavior with Exp

}

trait EqualsShowPlusNeg extends EqualsPlusNeg with ShowPlusNeg {
  type exp <: Exp

  trait Exp extends super[EqualsPlusNeg].Exp
    with super[ShowPlusNeg].Exp


  trait NumBehavior extends super[EqualsPlusNeg].NumBehavior with super[ShowPlusNeg].NumBehavior {
    self: BaseNum =>
  }

  class Num(v: Int) extends BaseNum(v) with NumBehavior with Exp

  trait PlusBehavior extends super[EqualsPlusNeg].PlusBehavior with super[ShowPlusNeg].PlusBehavior {
    self: BasePlus =>
  }

  class Plus(l: exp, r: exp) extends BasePlus(l, r) with PlusBehavior with Exp

  trait NegBehavior extends super[EqualsPlusNeg].NegBehavior with super[ShowPlusNeg].NegBehavior {
    self: BaseNeg =>
  }

  class Neg(term: exp) extends BaseNeg(term) with NegBehavior with Exp

}
def test1() = {
  import EqualsShowPlusNegInstance._
  println("EqualsShowPlusNegInstance:")
  println(new Num(3).show)
  // println(new Num(3).dble.show) // compilation error for dble
  println(new Plus(new Num(3), new Num(4)).show)
  // println(new Plus(new Num(3), new Num(4)).dble.show) // compilation error for dble
  println(new Num(3).eql(new Num(4)))

}

def test2() = {
  import ShowDblePlusNegInstance._
  println("ShowDblePlusNegInstance:")
  println(new Num(3).show)
  println(new Num(3).dble.show)
  println(new Plus(new Num(3), new Num(4)).show)
  println(new Plus(new Num(3), new Num(4)).dble.show)
  // println(new Num(3).eql(new Num(4)))  // compilation error for eql
}
然后你可以这样做:

trait Base {
  type exp <: Exp

  trait Exp {
    def eval: Int
  }


  class Num(val value: Int) extends Exp {
    def eval: Int = value
  }

  type BaseNum = Num
}

trait BasePlus extends Base {

  class Plus(val left: exp, val right: exp) extends Exp {
    def eval: Int = left.eval + right.eval
  }

  type BasePlus = Plus
}

trait BaseNeg extends Base {

  class Neg(val term: exp) extends Exp {
    def eval = -term.eval
  }

  type BaseNeg = Neg
}

trait BasePlusNeg extends BasePlus with BaseNeg

trait Show extends Base {
  type exp <: Exp

  trait Exp extends super.Exp {
    def show: String
  }

  trait NumBehavior extends Exp {
    self: BaseNum =>
    override def show: String = value.toString
  }

  final class Num(v: Int) extends BaseNum(v) with NumBehavior with Exp

}

trait ShowPlusNeg extends BasePlusNeg with Show {

  trait PlusBehavior {
    self: BasePlus =>
    def show = left.show + "+" + right.show;
  }

  final class Plus(l: exp, r: exp) extends BasePlus(l, r) with PlusBehavior with Exp

  trait NegBehavior {
    self: BaseNeg =>
    def show = "-(" + term.show + ")";
  }

  class Neg(t: exp) extends BaseNeg(t) with NegBehavior with Exp

}

trait DblePlusNeg extends BasePlusNeg {
  type exp <: Exp

  trait Exp extends super.Exp {
    def dble: exp
  }

  def Num(v: Int): exp

  def Plus(l: exp, r: exp): exp

  def Neg(t: exp): exp


  trait NumBehavior {
    self: BaseNum =>
    def dble = Num(value * 2)
  }

  final class Num(v: Int) extends BaseNum(v) with NumBehavior with Exp


  trait PlusBehavior {
    self: BasePlus =>
    def dble = Plus(left.dble, right.dble)
  }

  class Plus(l: exp, r: exp) extends BasePlus(l, r) with PlusBehavior with Exp


  trait NegBehavior {
    self: BaseNeg =>
    def dble = Neg(term.dble)
  }

  class Neg(t: exp) extends super.Neg(t) with NegBehavior with Exp

}

trait ShowDblePlusNeg extends ShowPlusNeg with DblePlusNeg {
  type exp <: Exp

  trait Exp extends super[ShowPlusNeg].Exp with super[DblePlusNeg].Exp;

  trait NumBehavior extends super[ShowPlusNeg].NumBehavior with super[DblePlusNeg].NumBehavior {
    self: BaseNum =>
  }

  final class Num(v: Int) extends BaseNum(v)
    with NumBehavior
    with Exp


  trait PlusBehavior extends super[ShowPlusNeg].PlusBehavior with super[DblePlusNeg].PlusBehavior {
    self: BasePlus =>
  }

  final class Plus(l: exp, r: exp) extends BasePlus(l, r)
    with PlusBehavior
    with Exp

  trait NegBehavior extends super[ShowPlusNeg].NegBehavior with super[DblePlusNeg].NegBehavior {
    self: BaseNeg =>
  }

  final class Neg(t: exp) extends BaseNeg(t)
    with NegBehavior
    with Exp

}

trait Equals extends Base {
  type exp <: Exp;

  trait Exp extends super.Exp {
    def eql(other: exp): Boolean;

    def isNum(v: Int): Boolean = false;
  }

  trait NumBehavior extends Exp {
    self: BaseNum =>
    def eql(other: exp): Boolean = other.isNum(value);

    override def isNum(v: Int) = v == value;
  }


  final class Num(v: Int) extends BaseNum(v) with NumBehavior with Exp

}

trait EqualsPlusNeg extends BasePlusNeg with Equals {
  type exp <: Exp;

  trait Exp extends super[BasePlusNeg].Exp
    with super[Equals].Exp {
    def isPlus(l: exp, r: exp): Boolean = false;

    def isNeg(t: exp): Boolean = false;
  }


  final class Num(v: Int) extends BaseNum(v)
    with NumBehavior // effectively super[Equals].NumBehavior
    with Exp


  trait PlusBehavior extends Exp {
    self: BasePlus =>
    def eql(other: exp): Boolean = other.isPlus(left, right);

    override def isPlus(l: exp, r: exp) = (left eql l) && (right eql r)
  }

  final class Plus(l: exp, r: exp) extends BasePlus(l, r) with PlusBehavior with Exp


  trait NegBehavior extends Exp {
    self: BaseNeg =>
    def eql(other: exp): Boolean = other.isNeg(term);

    override def isNeg(t: exp) = term eql t
  }

  final class Neg(t: exp) extends BaseNeg(t) with NegBehavior with Exp

}

trait EqualsShowPlusNeg extends EqualsPlusNeg with ShowPlusNeg {
  type exp <: Exp

  trait Exp extends super[EqualsPlusNeg].Exp
    with super[ShowPlusNeg].Exp


  trait NumBehavior extends super[EqualsPlusNeg].NumBehavior with super[ShowPlusNeg].NumBehavior {
    self: BaseNum =>
  }

  class Num(v: Int) extends BaseNum(v) with NumBehavior with Exp

  trait PlusBehavior extends super[EqualsPlusNeg].PlusBehavior with super[ShowPlusNeg].PlusBehavior {
    self: BasePlus =>
  }

  class Plus(l: exp, r: exp) extends BasePlus(l, r) with PlusBehavior with Exp

  trait NegBehavior extends super[EqualsPlusNeg].NegBehavior with super[ShowPlusNeg].NegBehavior {
    self: BaseNeg =>
  }

  class Neg(term: exp) extends BaseNeg(term) with NegBehavior with Exp

}
def test1() = {
  import EqualsShowPlusNegInstance._
  println("EqualsShowPlusNegInstance:")
  println(new Num(3).show)
  // println(new Num(3).dble.show) // compilation error for dble
  println(new Plus(new Num(3), new Num(4)).show)
  // println(new Plus(new Num(3), new Num(4)).dble.show) // compilation error for dble
  println(new Num(3).eql(new Num(4)))

}

def test2() = {
  import ShowDblePlusNegInstance._
  println("ShowDblePlusNegInstance:")
  println(new Num(3).show)
  println(new Num(3).dble.show)
  println(new Plus(new Num(3), new Num(4)).show)
  println(new Plus(new Num(3), new Num(4)).dble.show)
  // println(new Num(3).eql(new Num(4)))  // compilation error for eql
}
这里最重要的技巧是将在不同级别(如
Num
上具有多重继承的类拆分为:

  • 单个基类(例如
    base.Num
    )。这类类的类型别名通常是
    BaseNum
  • 行为
    特征(例如
    Show.numberhavior
    )包含所有逻辑并可进一步继承的每个级别(aka)
  • 每个级别的具体最终类(例如
    Show.Num
    此拆分允许通过仅继承一个基类并使用父类的所有
    行为
    特征连接的
    行为
    特征“增强”它来创建具体的类

    def test1() = {
      import EqualsShowPlusNegInstance._
      println("EqualsShowPlusNegInstance:")
      println(new Num(3).show)
      // println(new Num(3).dble.show) // compilation error for dble
      println(new Plus(new Num(3), new Num(4)).show)
      // println(new Plus(new Num(3), new Num(4)).dble.show) // compilation error for dble
      println(new Num(3).eql(new Num(4)))
    
    }
    
    def test2() = {
      import ShowDblePlusNegInstance._
      println("ShowDblePlusNegInstance:")
      println(new Num(3).show)
      println(new Num(3).dble.show)
      println(new Plus(new Num(3), new Num(4)).show)
      println(new Plus(new Num(3), new Num(4)).dble.show)
      // println(new Num(3).eql(new Num(4)))  // compilation error for eql
    }