在Scala中使用代数数据类型时在特征中定义通用方法

时间:2016-12-09 17:36:02

标签: scala abstract-data-type

我已经定义了一个抽象数据类型,我想让它相当通用和可扩展。

但是,scala类型系统给了我一个噩梦。

sealed trait Tree[+A] {
  def evaluateTree(): A = this match {
    case Leaf(value) => value
    case Branch_A1(op, left) => op(evaluateTree(left))
    case Branch_A2(op, left, right) => op(evaluateTree(left),evaluateTree(right))
  }
}
case object EmptyTree extends Tree[Nothing]
case class Leaf[A](value: A) extends Tree[A]
case class Branch_A1[A](op: A => A, left: Tree[A]) extends Tree[A]
case class Branch_A2[A](op: (A,A) => A, left: Tree[A], right: Tree[A]) extends Tree[A]

A 将是例如双。所以在这种情况下我有一个树,它有一个分支代表一个和两个参数的函数(Branch_A1,Branch_A2)

然而它没有编译。在op(evaluateTree(left))中,它说“它无法解决......有这样的参考”。

我可以将该功能从类中转移到更具功能性的模式中,但我想在对象设计之后执行此操作。我可以进行编译的唯一方法是:

sealed trait Tree[+A] {
  def evaluateTree(t: Tree[A]): A = this match {
    case Leaf(value) => value
    case Branch_A1(op, left) => op(evaluateTree(left))
    case Branch_A2(op, left, right) => op(evaluateTree(left),evaluateTree(right))
  }
}
case object EmptyTree extends Tree[Nothing]
case class Leaf[A](value: A) extends Tree[A]
case class Branch_A1[A](op: A => A, left: Tree[A]) extends Tree[A]
case class Branch_A2[A](op: (A,A) => A, left: Tree[A], right: Tree[A]) extends Tree[A]

这是愚蠢的,因为我需要传递对象的实例。

我需要告诉编译器thisTree[A]。所以我试过了:

sealed trait Tree[+A] {

  this: Tree[A] =>

  def evaluateTree(): A = this match {
    case Leaf(value) => value
    case Branch_A1(op, left) => op(evaluateTree(left))
    case Branch_A2(op, left, right) => op(evaluateTree(left),evaluateTree(right))
  }
}

编译器仍然不让我走,错误实际上是一样的。 我怎么解决这个问题?

1 个答案:

答案 0 :(得分:0)

看起来你的接收器搞砸了。 evaluateTree不接受论证。我假设您要评估子树,因为op(evaluateTree(left))应该是op(left.evaluateTree())

def evaluateTree(): A = this match {
  case Leaf(value) => value
  case Branch_A1(op, left) => op(left.evaluateTree())
  case Branch_A2(op, left, right) => op(left.evaluateTree(),right.evaluateTree())
}