I want to define a Swappable
trait with two values x,y
and a swap
method such that calling swap
on an object inheriting from Swappable
returns another object of the same type with x,y
switched. My best so far is:
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 }
}
}
But this isn't what I want because the return type of swap is some anonymous class, instead of the original class I started with, so I get errors like:
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
^
Is it possible to do what I'm trying to do? What is the correct type signature for swap?
I don't know how to do it, but I think maybe it would help to get a better idea of what exactly you want to happen. Consider a class like
case class Foo(x: Int, y: Int) extends Swappable[Int] {
val z = x
}
Now, if you have f = Foo(1, 2)
, should f.swap
give you a Foo
where x != z
? If so, there's no way within Scala to create a Foo
like that. If not, what does it really mean to "swap x and y"?
Perhaps what you're really looking for is something like this:
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)
}
But I'm not sure.
What about something like that:
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)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With