Scala中泛型函数的奇怪问题

时间:2014-08-07 02:30:06

标签: scala f#

我正在学习一些关于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))
                             ^

有谁可以指出我在哪里出错?

1 个答案:

答案 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 _
}