2

ほとんどの人がそれを気に入っているように見えるので、私はちょうどscalaを調べていました。だから私はFizzBu​​zzを書くと思っていましたが(HelloWorldよりもはるかに楽しいので)、何を入れてもPartialFunction、match / case構文でsを定義すると、isDefinedAtメソッドは常にtrueを返すように見えるため、ちょっと行き詰まります。誰かが私に欠けているものを説明できますか(またはこれはバグですか?)。Scala2.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)
4

1 に答える 1

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 = ...

scala2.10で次のように定義されているPartialFunctionobjectメソッドの呼び出しを使用するapply()

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

この場合、結果の関数fizzはすべてに対して定義されますxが、「wrapped」f(x)が呼び出されると、エラーが発生します。

于 2013-01-26T13:43:16.537 に答える