10

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

}
4

1 回答 1

15

它不会推断出的类型,T因为此时它唯一需要经过的就是arrayOneand 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))
}

如果您对它进行 curry,它工作正常的原因是 curried 方法实际上是一个接收第一个参数列表并返回需要其他(或其他)参数列表的函数的方法。因此,可以在第一个参数列表中决定重载,因此第二个参数列表可以利用推断类型。

于 2010-03-25T16:47:59.930 回答