Given this definition:
class Foo(var x: String) {}
object Helper {
def model[T](get: ⇒ T, set: T ⇒ Unit) : Model[T] = new Model[T] {
override def getObject(): T = get
override def setObject(obj: T) { set(obj) }
}
}
I try to call model like this:
val f = new Foo("initial")
val stringModel = model(f.x, f.x = _)
But that doesn’t work, the compiler gives me this, complaining about the underscore:
missing parameter type for expanded function ((x$1) => f.x = x$1)
If I change the definition of model to use two parameter lists like this:
def model[T](get: ⇒ T)(set: T ⇒ Unit) // rest is unchanged
Then I can call it like this:
model(f.x)(f.x = _)
Which I find nice and concise. I don’t really mind doing it like this, though it makes method overloading harder. I would like to understand, however, why the second variant works and the first one doesn’t?
The second variant works because Scala refines its types parameter-block by parameter-block. If you don’t specify the type of your input parameter for the function, it’s possible that it would change the type
Tthat it has inferred based on the first parameter. If you push it to a separate parameter block, Scala’s already decided whatTmust be by the time it hits that block, so it fills in the only possible value for the function argument type.