24

このモナド クラスがあるとします。

case class Foo[A](xs: List[A]) {
  def map[B](f: A => B) = Foo(xs map f)
  def flatMap[B](f: A => Foo[B]) = Foo(xs flatMap f.andThen(_.xs))
  def withFilter(p: A => Boolean) = {
    println("Filtering!")
    Foo(xs filter p)
  }
}

以下は、2.10.0 REPL セッションからのものです。

scala> for { (a, b) <- Foo(List(1 -> "x")) } yield a
res0: Foo[Int] = Foo(List(1))

2.10.1 の同じことを次に示します。

scala> for { (a, b) <- Foo(List(1 -> "x")) } yield a
Filtering!
res0: Foo[Int] = Foo(List(1))

これは (私には) まったく予想外であり、フィルタリングに追加の制約 (Scalaz\/や などEitherT) が必要な場合に、特に混乱を招くエラーにつながります。

2.10.1 のリリース ノートで、この変更に関する議論を見つけることができませんでした。この新しい脱糖動作が導入された場所と理由を誰か指摘できますか?

4

1 に答える 1

16

話はそれよりも複雑で、実際には 2.10.0 のリグレッションがプラグインされていました。

「no- withFilter」動作はc82ecabで導入されましたが、 SI-6968などの理由により、これは部分的に元に戻されました#1893。さらなる適応が続きました ( SI-6646SI-7183 )

あなたが探している重要な文は次のとおりです。

.isInstanceOf[Tuple2] の結果は typer の後まで静的に認識できないため、パーサーはパターン (a, b) が一致すると想定できません。

于 2013-07-02T13:35:45.647 に答える