2010-03-25 23 views
9

Soy nuevo en Scala (corrector de código Scala versión 2.7.7.final), y realmente no entiendo por qué requiere la persona que llama para proporcionar el tipo de parámetro cuando estamos utilizando funciones de orden superior.Valores de función genéricos de Scala (función anónima) - Falta el tipo de parámetro (error)

En el ejemplo siguiente, tengo un objeto independiente (Util) que tiene una función. Pero en el bloque Main, la persona que llama debe pasar el tipo de parámetro a la función anónima.

¿Por qué Scala no infiere el tipo de la función del tipo Array (es decir, String)? Hay alguna forma de hacer eso ?

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)) 

} 
+0

Solo faltan los trabajos para mí} en el objeto Util. –

+0

@Thomas funciona porque él especificó el tipo en la función. :-) –

+0

@Daniel La anotación de tipo es lo último que me molesta con este código. Me pregunto si sería grosero arreglarlo. Perdió la atención hasta la última línea. –

Respuesta

14

No inferir el tipo de T porque lo único que tiene que pasar en este punto sería arrayOne y arrayTwo. Sin embargo, Scala no usa el tipo de un parámetro para inferir el tipo de otro, probablemente porque causaría problemas con la sobrecarga del método. Sin embargo, funciona si curry que:

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)) 
} 

La razón de por qué funciona bien si curry es que un método de curry es en realidad un método de recepción de la primera lista de parámetros y el retorno de una función que requiere el otro (o otros) lista de parámetros. Debido a eso, la sobrecarga se puede decidir en la primera lista de parámetros, por lo que la segunda lista de parámetros puede aprovechar los tipos inferidos.

+0

Gracias Daniel ... Realmente disfruta de tu respuesta! – CHAPa

Cuestiones relacionadas