Сменная черта в Скале - PullRequest
       33

Сменная черта в Скале

5 голосов
/ 13 января 2012

Я хочу определить черту 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 }
  }
}

Но это не то, что я хочу, потому что возвращаемый тип свопа - это некий анонимный класс, а не исходный класс, с которого я начинал, поэтому я получаю такие ошибки, как:

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 ]

7 голосов
/ 13 января 2012

Я не знаю, как это сделать, но я думаю, что, возможно, это поможет лучше понять, что именно вы хотите, чтобы произошло.Рассмотрим класс типа

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

Но я не уверен.

3 голосов
/ 13 января 2012

Как насчет чего-то такого:

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