使用功能回调/代理模式实现scala缓存
cache using functional callbacks/ proxy pattern implementation scala
如何使用函数式编程实现缓存
几天前,我遇到了使用 scala 实现的回调和代理模式。
如果值不在地图中,则此代码应仅应用内部函数。
但是每次重新初始化地图并且值都消失了(这似乎很明显。
如何在不同的函数调用之间一次又一次地使用相同的缓存
class Aggregator{
def memoize(function: Function[Int, Int] ):Function[Int,Int] = {
val cache = HashMap[Int, Int]()
(t:Int) => {
if (!cache.contains(t)) {
println("Evaluating..."+t)
val r = function.apply(t);
cache.put(t,r)
r
}
else
{
cache.get(t).get;
}
}
}
def memoizedDoubler = memoize( (key:Int) => {
println("Evaluating...")
key*2
})
}
object Aggregator {
def main( args: Array[String] ) {
val agg = new Aggregator()
agg.memoizedDoubler(2)
agg.memoizedDoubler(2)// It should not evaluate again but does
agg.memoizedDoubler(3)
agg.memoizedDoubler(3)// It should not evaluate again but does
}
你不是在每次调用时声明一个新的 Map
吗?
def memoize(function: Function[Int, Int] ):Function[Int,Int] = {
val cache = HashMap[Int, Int]()
而不是指定 每个实例一个 of Aggregator
?
例如
class Aggregator{
private val cache = HashMap[Int, Int]()
def memoize(function: Function[Int, Int] ):Function[Int,Int] = {
我明白你在这里想做什么,它不起作用的原因是每次你调用 memoizedDoubler
它首先调用 memorize
。如果您希望它只调用一次 memoize
,则需要将 memoizedDoubler
声明为 val
而不是 def
。
val memoizedDoubler = memoize( (key:Int) => {
println("Evaluating...")
key*2
})
这个回答很好的解释了def
和val
的区别。
回答你的问题:
How to implement cache using functional programming
在函数式编程中没有可变状态的概念。如果您想更改某些内容(如缓存),您需要 return 更新缓存实例以及结果并将其用于下一次调用。
这里是按照该方法对您的代码进行的修改。 function
计算值,cache
合并到 Aggregator
。当调用 memoize
时,它是 returns 元组,其中包含计算结果(可能从缓存中获取)和应该用于下一次调用的新 Aggregator
。
class Aggregator(function: Function[Int, Int], cache:Map[Int, Int] = Map.empty) {
def memoize:Int => (Int, Aggregator) = {
t:Int =>
cache.get(t).map {
res =>
(res, Aggregator.this)
}.getOrElse {
val res = function(t)
(res, new Aggregator(function, cache + (t -> res)))
}
}
}
object Aggregator {
def memoizedDoubler = new Aggregator((key:Int) => {
println("Evaluating..." + key)
key*2
})
def main(args: Array[String]) {
val (res, doubler1) = memoizedDoubler.memoize(2)
val (res1, doubler2) = doubler1.memoize(2)
val (res2, doubler3) = doubler2.memoize(3)
val (res3, doubler4) = doubler3.memoize(3)
}
}
这会打印:
Evaluating...2
Evaluating...3
如何使用函数式编程实现缓存
几天前,我遇到了使用 scala 实现的回调和代理模式。 如果值不在地图中,则此代码应仅应用内部函数。 但是每次重新初始化地图并且值都消失了(这似乎很明显。
如何在不同的函数调用之间一次又一次地使用相同的缓存
class Aggregator{
def memoize(function: Function[Int, Int] ):Function[Int,Int] = {
val cache = HashMap[Int, Int]()
(t:Int) => {
if (!cache.contains(t)) {
println("Evaluating..."+t)
val r = function.apply(t);
cache.put(t,r)
r
}
else
{
cache.get(t).get;
}
}
}
def memoizedDoubler = memoize( (key:Int) => {
println("Evaluating...")
key*2
})
}
object Aggregator {
def main( args: Array[String] ) {
val agg = new Aggregator()
agg.memoizedDoubler(2)
agg.memoizedDoubler(2)// It should not evaluate again but does
agg.memoizedDoubler(3)
agg.memoizedDoubler(3)// It should not evaluate again but does
}
你不是在每次调用时声明一个新的 Map
吗?
def memoize(function: Function[Int, Int] ):Function[Int,Int] = {
val cache = HashMap[Int, Int]()
而不是指定 每个实例一个 of Aggregator
?
例如
class Aggregator{
private val cache = HashMap[Int, Int]()
def memoize(function: Function[Int, Int] ):Function[Int,Int] = {
我明白你在这里想做什么,它不起作用的原因是每次你调用 memoizedDoubler
它首先调用 memorize
。如果您希望它只调用一次 memoize
,则需要将 memoizedDoubler
声明为 val
而不是 def
。
val memoizedDoubler = memoize( (key:Int) => {
println("Evaluating...")
key*2
})
这个回答很好的解释了def
和val
的区别。
回答你的问题:
How to implement cache using functional programming
在函数式编程中没有可变状态的概念。如果您想更改某些内容(如缓存),您需要 return 更新缓存实例以及结果并将其用于下一次调用。
这里是按照该方法对您的代码进行的修改。 function
计算值,cache
合并到 Aggregator
。当调用 memoize
时,它是 returns 元组,其中包含计算结果(可能从缓存中获取)和应该用于下一次调用的新 Aggregator
。
class Aggregator(function: Function[Int, Int], cache:Map[Int, Int] = Map.empty) {
def memoize:Int => (Int, Aggregator) = {
t:Int =>
cache.get(t).map {
res =>
(res, Aggregator.this)
}.getOrElse {
val res = function(t)
(res, new Aggregator(function, cache + (t -> res)))
}
}
}
object Aggregator {
def memoizedDoubler = new Aggregator((key:Int) => {
println("Evaluating..." + key)
key*2
})
def main(args: Array[String]) {
val (res, doubler1) = memoizedDoubler.memoize(2)
val (res1, doubler2) = doubler1.memoize(2)
val (res2, doubler3) = doubler2.memoize(3)
val (res3, doubler4) = doubler3.memoize(3)
}
}
这会打印:
Evaluating...2
Evaluating...3