In researching how to do Memoization in Scala, I\'ve found some code I didn\'t grok. I\'ve tried to look this particular \"thing\" up, but don\'t know by what to call it; i.
One more word about this extends (A => B)
: the extends
here is not required, but necessary if the instances of Memo
are to be used in higher order functions or situations alike.
Without this extends (A => B)
, it's totally fine if you use the Memo
instance fibonacci
in just method calls.
case class Memo[A,B](f: A => B) {
private val cache = scala.collection.mutable.Map.empty[A, B]
def apply(x: A):B = cache getOrElseUpdate (x, f(x))
}
val fibonacci: Memo[Int, BigInt] = Memo {
case 0 => 0
case 1 => 1
case n => fibonacci(n-1) + fibonacci(n-2)
}
For example:
Scala> fibonacci(30)
res1: BigInt = 832040
But when you want to use it in higher order functions, you'd have a type mismatch error.
Scala> Range(1, 10).map(fibonacci)
:11: error: type mismatch;
found : Memo[Int,BigInt]
required: Int => ?
Range(1, 10).map(fibonacci)
^
So the extends
here only helps to ID the instance fibonacci
to others that it has an apply
method and thus can do some jobs.