将元组传递给泛型方法时出错

时间:2016-10-20 13:57:55

标签: scala generics

这是一个记忆/缓存中间结果的函数:

 def memoize[I, O](f: I => O) = new scala.collection.mutable.HashMap[I, O]() {
   override def apply(key: I): O = getOrElseUpdate(key, f(key))    
 }

这适用于以下代码,

val double: Int=>Int = memoize {
    _*2
}

但是,当我尝试使用元组作为输入参数(I)时,它显示编译时错误,

val isGivenNumIsHead:(List[Int], Int) => Boolean = memoize {
  case (Nil, _) => false
  case (a:: as, n) => a == n
}

编译时错误是:

类型mutable.HashMap的表达式[Nothing,Boolean] {def apply(key:Nothing):Boolean}不符合预期类型(List [Int],Int)=>布尔

这是否与擦除有关。

我该如何解决?

1 个答案:

答案 0 :(得分:4)

我假设你想使用元组作为HashMap中的键。考虑到这一点,这是解释。

memoize的实际返回类型为scala.collection.mutable.HashMap[_,_]。这被分配给double Int => IntFunction1[Int,Int](一个取整数并给出一个整数的函数)。编译器不会抛出错误,因为mutable.HashMap扩展了scala.collection.mutable.MapLike,而scala.collection.MapLike又扩展了scala.PartialFunction[A, B],而scala.Function1[A, B]又扩展了val functionName : A => B = a => {return b},后者又扩展了val function : (A) => B = a => {return b}。因此没有编译错误。

另一方面,获取一个参数并返回一个值的函数的语法是val function: (A => B) = a => {return b},或者可以写为List[Int],Intval isGivenNumIsHead:((List[Int], Int)) => Boolean = memoize { case (Nil, _) => false case (a:: as, n) => a == n } 。您已经使用了第二种方法。在这种情况下,A的值应该是单一类型。您使用的{{1}}不是单一类型。请注意,我故意删除括号。因此,为了将其作为单个类型并将其作为元组传递,您必须再使用一组括号。正确的语法是

{{1}}

请注意使用额外的括号使其成为元组。