这是一个记忆/缓存中间结果的函数:
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)=>布尔
这是否与擦除有关。
我该如何解决?
答案 0 :(得分:4)
我假设你想使用元组作为HashMap中的键。考虑到这一点,这是解释。
memoize
的实际返回类型为scala.collection.mutable.HashMap[_,_]
。这被分配给double
Int => Int
或Function1[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],Int
或val isGivenNumIsHead:((List[Int], Int)) => Boolean = memoize {
case (Nil, _) => false
case (a:: as, n) => a == n
}
。您已经使用了第二种方法。在这种情况下,A的值应该是单一类型。您使用的{{1}}不是单一类型。请注意,我故意删除括号。因此,为了将其作为单个类型并将其作为元组传递,您必须再使用一组括号。正确的语法是
{{1}}
请注意使用额外的括号使其成为元组。