使用case语法定义的Scala PartialFunction总是在isDefinedAt上返回true

时间:2013-01-26 13:07:29

标签: scala

我只是在研究scala,因为大多数人似乎都喜欢它。所以我以为我会编写FizzBu​​zz(因为它比HelloWorld更有趣),但是有点卡住,因为无论我放入什么,如果我用匹配/案例语法定义我的PartialFunction s { {1}}方法似乎总是返回true。任何人都可以向我解释我错过了什么(或者这是一个错误?)。我正在使用Scala 2.10.0版本。

代码:

isDefinedAt

堆栈跟踪:

object Main extends App {
  def applyAndJoin[A, B](f: PartialFunction[A, B],
    g: PartialFunction[A, B])(h: (B, B) => B): PartialFunction[A, B] = {
    PartialFunction[A, B] {
      case a if (f isDefinedAt a) && (g isDefinedAt a) => h(f(a), g(a))
    } orElse f orElse g
  }

  val fizz = PartialFunction[Int, String] { case a if a % 3 == 0 => "Fizz" }
  val buzz = PartialFunction[Int, String] { case a if a % 5 == 0 => "Buzz" }
  val makeString = PartialFunction[Int, String] { case a => a.toString }
  val fizzBuzz = applyAndJoin(fizz, buzz)((a, b) => a + b) orElse makeString
  1 to 100 collect fizzBuzz foreach println //this fails because scala thinks
                                            //that fizz is defined at 1
}

1 个答案:

答案 0 :(得分:7)

您的PartialFunction定义没有按照您的想法进行,您应该编写

val fizz: PartialFunction[Int, String] = { case a if a % 3 == 0 => "Fizz" }
val buzz: PartialFunction[Int, String] = { case a if a % 5 == 0 => "Buzz" }
val makeString: PartialFunction[Int, String] = { case a => a.toString }

通过这种方式,您可以定义PartialFunction[Int, String]类型的变量,其值为匿名定义{ case a if ...}


相反,您正在定义变量

val fizz = ...

使用对PartialFunction对象apply()方法的调用,在scala 2.10中定义为

def apply[A, B](f: A => B): PartialFunction[A, B] = { case x => f(x) }

在这种情况下,为每个fizz定义了结果函数x,但是当调用“包裹的”f(x)时,会出现错误。