Значения универсальной функции Scala (анонимная функция) - тип параметра отсутствует (ошибка)

Я новичок в Scala (исполнитель кода Scala версии 2.7.7.final), и я действительно не понимаю, почему он требует, чтобы вызывающий объект предоставлял тип параметра, когда мы используем функции высокого порядка.

В приведенном ниже примере у меня есть один автономный объект (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))

}

person CHAPa    schedule 25.03.2010    source источник
comment
У меня работает, только в объекте Util отсутствует}.   -  person Thomas Jung    schedule 25.03.2010
comment
@Thomas это работает, потому что он указал тип в функции. :-)   -  person Daniel C. Sobral    schedule 25.03.2010
comment
@Daniel Аннотации типов - последнее, что меня беспокоит в этом коде. Интересно, было бы грубо исправить это. Упустил внимание до последней строчки.   -  person Thomas Jung    schedule 25.03.2010
comment
@ Томас Ты хочешь исправить что-нибудь еще? Просто сделай это, нет проблем! : D   -  person CHAPa    schedule 25.03.2010


Ответы (1)


Он не делает вывод о типе 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))
}

Причина, по которой он отлично работает, если вы карри, заключается в том, что каррированный метод на самом деле является методом, получающим первый список параметров и возвращающим функцию, для которой требуется другой (или другие) список параметров. По этой причине решение о перегрузке может быть решено в первом списке параметров, поэтому второй список параметров может использовать преимущества предполагаемых типов.

person Daniel C. Sobral    schedule 25.03.2010