Scala通用函数值(匿名函数) - 缺少参数类型(错误) [英] Scala Generic Function Values (Anonymous Function) - Missing Parameter Type (Error)

查看:191
本文介绍了Scala通用函数值(匿名函数) - 缺少参数类型(错误)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Scala(Scala代码运行器版本2.7.7.final )的新手,我真的不明白为什么它需要调用者在使用高时提供参数类型

在下面的例子中,我有一个独立的对象( Util ),它有一个函数。但是在 Main 块中,调用者必须将参数类型传递给匿名函数。



为什么Scala不是从 Array 类型(即 String )推断函数的类型?有没有办法做到这一点?

  object Util {

//只是为了好玩!假设arrayOne和arrayTwo的长度都是相同的。
//将把arrayOne中的元素交换到ArrayTwo。
def swap [T](arrayOne:Array [T],arrayTwo:Array [T],f:(T,T)=>(T,T)){
for(i< (arrayOne.length min arrayTwo.length)){
val(left,right)= f(arrayOne(i),arrayTwo(i))
arrayOne(i)= left
arrayTwo(i)= right
}
}
}

对象Main扩展应用程序{

val arrayOne = Array(A ,B,C)
val arrayTwo = Array(D,E,F)

//如果未指定类型String,则编译器抛出Missing Parameter Type错误

Util swap(arrayOne,arrayTwo,(elem1:String,elem2:String)=>(elem2,elem1))

}


解决方案

它不会推断 T ,因为它现在唯一要做的事情就是 arrayOne arrayTwo 。但是,Scala并未使用一个参数的类型来推断另一个参数的类型,可能是因为它会导致方法重载问题。但是,如果你使用它,它就可以工作:

  Object Util {

//只是为了好玩!假设arrayOne和arrayTwo的长度都是相同的。
//将把arrayOne中的元素交换到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&< arrayTwo.length){
tuple = f( arrayOne(i),arrayTwo(i))
arrayOne(i)= tuple._1
arrayTwo(i)= tuple._2
i + = 1
}
}
}

对象Main扩展应用程序{

// val在下面工作正常 - 对象是可变的
val arrayOne = Array(A (arrayOne,arrayTwo))(()),(B,C))
val arrayTwo = Array(D,E,F)

elem1,elem2)=>(elem2,elem1))
//奇怪的圆括号是由混合操作符和currying
引起/​​/也可以这样写:
// Util.swap(arrayOne,arrayTwo)((elem1,elem2)=>(elem2,elem1))
}

如果你咖喱它的原因,它的工作原理是咖喱方法是行为一个方法是接收第一个参数列表并返回一个需要其他(或其他)参数列表的函数。因此,重载可以在第一个参数列表中决定,所以第二个参数列表可以利用推断的类型。


I'm new to Scala (Scala code runner version 2.7.7.final), and I really don't understand why it requires the caller to provide the parameter type when we are using high order functions.

In the sample below, I have one stand alone object ( Util ) that has one function. But in the Main block, the caller must pass the parameter type to the anonymous function.

Why does Scala not infer the type of the function from the Array type (i.e. String)? Is there any way to do that ?

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

}

解决方案

It doesn't infer the type of T because the only thing it has to go by at this point would be arrayOne and arrayTwo. However, Scala does not use the type of one parameter to infer the type of another, probably because it would cause problems with method overloading. However, it works if you curry it:

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

The reason why it works fine if you curry it is that a curried method is actually a method receiving the first parameter list and returning a function that requires the other (or others) parameter list. Because of that, overloading can be decided in the first parameter list, so the second parameter list can take advantage of inferred types.

这篇关于Scala通用函数值(匿名函数) - 缺少参数类型(错误)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆