I'm creating a simple cache trait (to cache my functions easily):
trait Cache[A,B] {
def _calc(v:A):B
private var cache = Map[A,B]()
def calc(v:A):B = {
cache.get(v) match {
case Some(x) => x
case None =>
val x = _calc(v)
cache += (v -> x)
x
}
}
}
The usage:
object Sol extends Cache[Int,Int] {
def _calc(v:Int):Int = { /* do something here */ }
}
Sol.calc(5)
It works properly, but the problem arises when I need to cache functions with more arguments - so I need to develop traits Cache2, Cache3, all copy-pasting code from the first trait.
The possible workaround is to convert functions with multiple arguments to functions accepting a tuple, but that does not seem right.
Is there a way to do it more generally and to avoid DRY principle violation?
Classes and objects can extend traits, but traits cannot be instantiated and therefore have no parameters.
Unlike a class, Scala traits cannot be instantiated and have no arguments or parameters. However, you can inherit (extend) them using classes and objects.
You could use a script to generate the scala source of your functions with different arities.
This approach may seem ugly, but it is used even on Scala library to define the source code of TupleN
, ProductN
and FunctionN
(where N
is an int smaller than 21).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With