Scala中的可交换特征

时间:2012-01-12 21:47:27

标签: scala inheritance traits

我想定义一个Swappable特征,其中包含两个值x,y和一个swap方法,以便在从swap继承的对象上调用Swappable返回另一个切换了x,y的相同类型的对象。到目前为止,我最好的是:

trait Swappable[T] {
  val x: T
  val y: T
  def swap: Swappable[T] = {
    val (a,b) = (x,y)
    new Swappable[T] { val x=b; val y=a }
  }
}

但这不是我想要的,因为swap的返回类型是一些匿名类,而不是我开始使用的原始类,所以我得到如下错误:

def direct[S<:Swappable[Int]](s: S): S = if (s.x > s.y) s else s.swap 
<console>:32: error: type mismatch;
 found   : Swappable[Int]
 required: S
       def direct[S<:Swappable[Int]](s: S): S = if (s.x > s.y) s else s.swap
                                                                        ^

我可以做我想做的事吗? swap的正确类型签名是什么?

2 个答案:

答案 0 :(得分:7)

我不知道该怎么做,但我想也许有助于更好地了解你想要发生什么。考虑像

这样的类
case class Foo(x: Int, y: Int) extends Swappable[Int] {
    val z = x
}

现在,如果你有f = Foo(1, 2),那么f.swap应该Foo给你x != z吗?如果是这样,Scala内部就无法像这样创建Foo。如果不是,“交换x和y”真正意味着什么?

也许你真正想要的是这样的:

trait Swappable[A,T] {
    this: A =>

    val x: T
    val y: T
    def cons(x: T, y: T): A

    def swap = cons(y, x)
}

case class Foo(x: Int, y: Int) extends Swappable[Foo,Int] {
    val z = x

    def cons(x: Int, y: Int) = copy(x=x, y=y)
}

但我不确定。

答案 1 :(得分:3)

这样的事情:

trait Swappable[T] {
  type A
  val x: T
  val y: T

  def create(a: T, b: T): A
  def swap = create(y, x)
}

case MySwappable[T](x: T, y: T) extends Swappable[T] {
  type A = MySwappable
  def create(a: T, b: T) = MySwappable(a, b)
}