我只是在研究 scala,因为大多数人似乎都喜欢它。所以我想我会写 FizzBuzz(因为它比 HelloWorld 有趣得多),但我有点卡住了,因为无论我在其中添加什么,如果我PartialFunction
用匹配/大小写语法定义我的 s,他们的isDefinedAt
方法似乎总是返回 true . 谁能向我解释我缺少什么(或者这是一个错误?)。我正在使用 Scala 2.10.0 版本。
代码:
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
}
堆栈跟踪:
Exception in thread "main" scala.MatchError: 1 (of class java.lang.Integer)
at Main$$anonfun$1.apply(Main.scala:9)
at Main$$anonfun$1.apply(Main.scala:9)
at scala.PartialFunction$$anonfun$apply$1.applyOrElse(PartialFunction.scala:242)
at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:33)
at Main$$anonfun$applyAndJoin$1.apply(Main.scala:5)
at scala.PartialFunction$$anonfun$apply$1.applyOrElse(PartialFunction.scala:242)
at scala.PartialFunction$OrElse.apply(PartialFunction.scala:162)
at scala.collection.TraversableLike$$anonfun$collect$1.apply(TraversableLike.scala:278)
at scala.collection.immutable.Range.foreach(Range.scala:142)
at scala.collection.TraversableLike$class.collect(TraversableLike.scala:278)
at scala.collection.AbstractTraversable.collect(Traversable.scala:105)
at Main$delayedInit$body.apply(Main.scala:13)
at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App$$anonfun$main$1.apply(App.scala:71)
at scala.App$$anonfun$main$1.apply(App.scala:71)
at scala.collection.immutable.List.foreach(List.scala:309)
at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
at scala.App$class.main(App.scala:71)
at Main$.main(Main.scala:1)
at Main.main(Main.scala)