Scala中的可交换特征

Scala中的可交换特征,scala,inheritance,traits,Scala,Inheritance,Traits,我想用两个值x,y和swap方法定义一个swap特征,这样在继承自Swappable的对象上调用swap会返回另一个类型相同的对象,并且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的

我想用两个值
x,y
swap
方法定义一个
swap
特征,这样在继承自
Swappable
的对象上调用
swap
会返回另一个类型相同的对象,并且
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
                                                                        ^
def direct[S S.y)S else S.swap
:32:错误:类型不匹配;
找到:可交换[Int]
必填项:S
def直接[S.y]S其他S.swap
^

是否有可能做我想做的事?交换的正确类型签名是什么?

< p>我不知道怎么做,但我想这可能有助于更好地了解你想要发生什么。
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)
}

但是我不确定。

这样的事情怎么样:

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)
}

非常好!您指出了一个很好的观点,即交换的概念通常不清楚。在我的情况下,我将只使用case类
Foo(x:T,y:T)扩展
Swappable
不包含额外的值,但是Scala没有太多方法知道这一点。因此我想我将把
交换
方法的实现留给每个继承类(这基本上就是您通过额外的方法
cons
)来做的。做这件事的关键(我没有想到)正在将额外的类型参数
A
传递到
Swappable
,这让继承类决定返回类型应该是什么。谢谢!对,这与Owen的解决方案非常相似。仅供参考,这个问题被称为“MyType”:(Scala中还没有无样板的答案)