As @ghik says, there are type inference limitations when you use method (or in this case constructor) overloading. In general, you should try to avoid overloading, it is almost never good practice.
A work around here would be to use a second parameter list, e.g.
trait Generator {
def generateArray(idim: Int): Array[Double]
}
class Point(iDim: Int, data: Array[Double], f: Array[Double] => Double) {
def this(idim: Int, gen: Generator)(f: Array[Double] => Double) {
this(idim, gen.generateArray(idim), f)
}
}
val obj = new Generator {
def generateArray(idim: Int) = new Array[Double](idim)
}
def f(arr: Array[Double]) = arr.sum
new Point(33, obj)(f)
Putting a function argument into a second parameter list is common in Scala, as it allows a convenient syntax for function literals. Because new Point(...) { ... }
would be interpreted as extending the class with an anonymous body, the better solution—and getting rid of overloading—is to use the companion object:
object Point {
def apply(idim: Int, gen: Generator)(f: Array[Double] => Double) =
new Point(idim, gen.generateArray(idim), f)
}
class Point(iDim: Int, data: Array[Double], f: Array[Double] => Double)
Point(33, obj)(f)
Point(33, obj) { arr => arr.sum / arr.size }
(Note: you can also write the apply
method with one parameter list. Because it is not overloaded, you don't have the problem with having to state the underscore)