Interesting Scala typing solution, doesn't work in 2.7.7?

Posted by djc on Stack Overflow See other posts from Stack Overflow or by djc
Published on 2010-05-02T12:50:00Z Indexed on 2010/05/02 12:58 UTC
Read the original article Hit count: 168

Filed under:

I'm trying to build some image algebra code that can work with images (basically a linear pixel buffer + dimensions) that have different types for the pixel. To get this to work, I've defined a parametrized Pixel trait with a few methods that should be able to get used with any Pixel subclass. (For now, I'm only interested in operations that work on the same Pixel type.) Here it is:

trait Pixel[T <: Pixel[T]] {

    def mul(v: Double): T
    def max(v: T): T
    def div(v: Double): T
    def div(v: T): T

}

Now I define a single Pixel type that has storage based on three doubles (basically RGB 0.0-1.0), I've called it TripleDoublePixel:

class TripleDoublePixel(v: Array[Double]) extends Pixel[TripleDoublePixel] {

    var data: Array[Double] = v

    def this() = this(Array(0.0, 0.0, 0.0))

    def toString(): String = {
        "(" + data(0) + ", " + data(1) + ", " + data(2) + ")"
    }

    def increment(v: TripleDoublePixel) {
        data(0) += v.data(0)
        data(1) += v.data(1)
        data(2) += v.data(2)
    }

    def mul(v: Double): TripleDoublePixel = {
        new TripleDoublePixel(data.map(x => x * v))
    }

    def div(v: Double): TripleDoublePixel = {
        new TripleDoublePixel(data.map(x => x / v))
    }

    def div(v: TripleDoublePixel): TripleDoublePixel = {
        var tmp = new Array[Double](3)
        tmp(0) = data(0) / v.data(0)
        tmp(1) = data(1) / v.data(1)
        tmp(2) = data(2) / v.data(2)
        new TripleDoublePixel(tmp)
    }

    def max(v: TripleDoublePixel): TripleDoublePixel = {
        val lv = data(0) * data(0) + data(1) * data(1) + data(2) * data(2)
        val vv = v.data(0) * v.data(0) + v.data(1) * v.data(1) + v.data(2) * v.data(2)
        if (lv > vv) (this) else v
    }

}

Now I want to write code to use this, that doesn't have to know what type the pixels are. For example:

def idiv[T](a: Image[T], b: Image[T]) {
    for (i <- 0 until a.data.size) {
        a.data(i) = a.data(i).div(b.data(i))
    }
}

Unfortunately, this doesn't compile:

(fragment of lindet-gen.scala):145:
error: value div is not a member of T
                 a.data(i) = a.data(i).div(b.data(i))

I was told in #scala that this worked for someone else, but that was on 2.8. I've tried to get 2.8-rc1 going, but it doesn't compile for me. Is there any way to get this to work in 2.7.7?

© Stack Overflow or respective owner

Related posts about scala