问题
Can someone tell me why the following does not work?
object TestObject {
def map(f: (Double, Double) => Double, x2: Array[Double]) = {
val y = x2.zip( x2 )
val z = y.map(f)
z
}
}
Produces this error:
type mismatch; found : (Double, Double) => Double required: ((Double, Double)) => ?
回答1:
In this snippet, f
is a function taking two Double
parameters and returning a Double
.
You are attempting to call f
by passing a single argument of type Tuple2[Double,Double]
.
You can fix this by changing the type of f
in the first place:
object TestObject {
def map(f: ((Double, Double)) => Double, x2: Array[Double]) = {
val y = x2.zip( x2 )
val z = y.map(f)
z
}
}
You could also declare it as f: Tuple2[Double, Double] => Double
to be clearer (this is entirely equivalent).
Conversely, you could change your call like this:
object TestObject {
def map(f: (Double, Double) => Double, x2: Array[Double]) = {
val y = x2.zip( x2 )
val z = y.map(f.tupled)
z
}
}
tupled
automagically transforms your (Double, Double) => Double
function into a Tuple2[Double, Double] => Double
function.
Keep in mind however that the conversion will be done on each call to TestObject.map
回答2:
There is a subtle difference between
f: (Double, Double) => Double // two Double arguments -> Double
and
f: ((Double, Double)) => Double // one Tuple2[Double, Double] argument -> Double
y
is an Array[(Double, Double)]
, so it expects a method that takes a tuple and returns something, but the first f
defined above doesn't match that.
You can do y.map(f.tupled)
to go from the first to the second, or change the signature of f
.
回答3:
I think your issue is that f
expects two Double
arguments but you're attempting to pass it a single tuple: f((1, 2))
is different from f(1, 2)
.
Change the type of f to ((Double, Double) => Double)
and it should work.
来源:https://stackoverflow.com/questions/17109855/scala-strange-implicit-boxing-conversion-error