Я плохо знаком с Scala (версия 2.7.7.final бегуна кода Scala), и я действительно не понимаю, почему она требует, чтобы вызывающая сторона обеспечила тип параметра, когда мы используем высокого уровня функции.
В образце ниже, у меня есть один одинокий объект ( Util
) это имеет одну функцию. Но в Main
блок, вызывающая сторона должна передать тип параметра анонимной функции.
Почему Scala не выводит тип функции от Array
введите (т.е. String
)? Там какой-либо путь состоит в том, чтобы сделать это?
object Util {
// Just for fun! Suppose that the arrayOne and arrayTwo are all the same length.
// will swap the elements from arrayOne to ArrayTwo.
def swap[T](arrayOne:Array[T], arrayTwo:Array[T] , f:(T,T) =>(T,T)) {
for(i <- 0 until (arrayOne.length min arrayTwo.length)){
val (left, right) = f(arrayOne(i),arrayTwo(i))
arrayOne(i) = left
arrayTwo(i) = right
}
}
}
object Main extends Application {
val arrayOne = Array("A","B","C")
val arrayTwo = Array("D","E","F")
//If not specified the type String,the compiler throws "Missing Parameter Type" error
Util swap(arrayOne, arrayTwo,(elem1:String,elem2:String)=>(elem2,elem1))
}
Это не делает вывод о типе T
, потому что единственное, что нужно пройти на данный момент, это arrayOne
и arrayTwo
. Однако Scala не использует тип одного параметра для определения типа другого, вероятно, потому, что это может вызвать проблемы с перегрузкой метода. Однако он работает, если вы его карри:
Object Util {
// Just for fun! Suppose that the arrayOne and arrayTwo are all the same length.
// will swap the elements from arrayOne to ArrayTwo.
def swap[T](arrayOne:Array[T], arrayTwo:Array[T])(f:(T,T) =>(T,T)) : Unit = {
var i = 0
var tuple :Tuple2[T,T] = null
while(i < arrayOne.length && i < arrayTwo.length){
tuple =f(arrayOne(i),arrayTwo(i))
arrayOne(i) = tuple._1
arrayTwo(i) = tuple._2
i+=1
}
}
}
object Main extends Application {
// val works fine below -- the object is mutable
val arrayOne = Array("A","B","C")
val arrayTwo = Array("D","E","F")
(Util swap(arrayOne, arrayTwo))((elem1,elem2)=>(elem2,elem1))
// The weird parenthesis is caused by mixing operator notation and currying
// One could also write it like this:
// Util.swap(arrayOne, arrayTwo)((elem1,elem2)=>(elem2,elem1))
}
Причина, по которой он отлично работает, если вы карри, заключается в том, что каррированный метод на самом деле является методом, получающим первый список параметров и возвращающим функцию, которая требует другой (или другие) список параметров . По этой причине решение о перегрузке может быть решено в первом списке параметров, поэтому второй список параметров может использовать преимущества предполагаемых типов.