问题
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