I'm having difficulty transitioning from the world of C++/Templates to scala. I'm used to being able to use any operation on a template parameter T that I want, as long as anything I use to instantiate T with supports those operations (compile-time Duck typing, basically). I cannot find the corresponding idiom in Scala that will allow me to define an abstract class with a single type parameter, and which expects a certain interface for type T.
What I have almost works, but I cannot figure out how to tell the abstract class (Texture[T <: Summable[T]]) that T supports conversion/construction from an Int. How can I add the implicit conversion to the trait Summable so that Texture knows T supports the conversion?
trait Summable[T] {
def += (v : T) : Unit
def -= (v : T) : Unit
}
object Int4 { implicit def int2Int4(i : Int) = new Int4(i, i, i, i) }
class Int4 (var x : Int, var y : Int, var z : Int, var w : Int) extends Summable[Int4] {
def this (v : Int) = this(v, v, v, v)
def += (v : Int4) : Unit = { x += v.x; y += v.y; z += v.z; w += v.w }
def -= (v : Int4) : Unit = { x -= v.x; y -= v.y; z -= v.z; w -= v.w }
}
abstract class Texture[Texel <: Summable[Texel]] {
var counter : Texel
def accumulate(v : Texel) : Unit = { counter += v }
def decrement() : Unit = { counter -= 1 } //< COMPILE ERROR HERE, fails to find implicit
}
class Int4Target extends Texture[Int4] {
var counter : Int4 = new Int4(0, 1, 2, 3)
}
You can define an implicit constructor parameter like this
abstract class Texture[Texel <: Summable[Texel]](implicit int2Texel: Int => Texel) {
//...
This essentially tells the compiler that in order to construct an instance of Texture
, there must be an implicit conversion function available from Int
to Texel
. Assuming you have such a function defined somewhere in scope (which you do), you should no longer get a compile error.
Edit2: Ok I originally misread your code, you actually only need one implicit parameter from Int => Texel
. Your code compiles for me with the above modification.
Edit: You'll actually need 2 conversion functions, one from Texel => Int
and another from Int => Texel
in order to properly reassign the var
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