我正在学习一些关于Scala的过程,以便了解它与F#的比较,这是我花费大部分时间的时间。我尝试了一种非常简单的函数记忆技术。在F#中我会使用这样的东西:
open System.Collections.Generic
let memoize (f : 'a -> 'b) =
// A dictionary in which to cache results of previous
// calls of the function
let dict = new Dictionary<'a, 'b>()
let memoizedFunction input =
match dict.TryGetValue(input) with
| true, x -> x
| false, _ ->
let answer = f input
dict.Add(input, answer)
answer
memoizedFunction
在Scala中尝试生成相同版本的内容时,我想出了以下内容:
def memoize[A, B](f: A => B): A => B = {
val dict = collection.mutable.WeakHashMap[A, B]()
def memoizedFunction[A, B](input: A): B =
dict.get(input) match {
case x: Some[B] => x
case _ =>
val answer = f(input)
dict += ((input, answer))
answer
}
memoizedFunction _
}
当我尝试定义此功能时,我在REPL中收到一些错误:
<console>:11: error: type mismatch;
found : input.type (with underlying type A)
required: A
dict.get(input) match {
^
<console>:14: error: type mismatch;
found : input.type (with underlying type A)
required: A
val answer = f(input)
^
<console>:15: error: type mismatch;
found : input.type (with underlying type A)
required: A
dict += ((input, answer))
^
有谁可以指出我在哪里出错?
答案 0 :(得分:2)
memoizedFunction
上的类型参数会影响外部类型参数。 Scala仿制药的细节让我感到厌烦,但这就是为什么输入A的类型不是Scala正在寻找的A.
此外,x: Some[B]
与memoizedFunction
的返回类型冲突,即B.匹配选项的惯用方法是Some(x) => // do something with x
。
所以我已经纠正了这两件事:
def memoize[A, B](f: A => B): A => B = {
val dict = collection.mutable.WeakHashMap[A, B]()
def memoizedFunction(input: A): B =
dict.get(input) match {
case Some(x) => x
case _ =>
val answer = f(input)
dict += ((input, answer))
answer
}
memoizedFunction _
}