2010-03-25 104 views
9

我是新来的斯卡拉(斯卡拉代码亚军版本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)) 

} 
+0

对我来说只有a}在Util对象中缺失。 –

+0

@Thomas它的工作原理是因为他在函数中指定了类型。 :-) –

+0

@Daniel类型注释是这个代码困扰我的最后一件事。我想知道是否要解决它是不礼貌的。把注意力转移到最后一行。 –

回答

14

它并不推断T的类型,因为它具有唯一通过在这一点上走会arrayOnearrayTwo。但是,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)) 
} 

之所以它,如果你咖喱它是一个令行禁止方法实际上是接收的第一个参数列表,并返回需要其他的功能的方法工作正常(或其他)参数列表。因此,可以在第一个参数列表中决定重载,因此第二个参数列表可以利用推断的类型。

+0

谢谢丹尼尔..真的很享受你的回答! – CHAPa