2

Scala 言語仕様のセクション6.19には次のように書かれています。

理解のためのAfor (p <- e) yield e0はに翻訳されますe.map { case p => e0 }

そう...

scala> val l : List[Either[String, Int]] = List(Left("Bad"), Right(1))
l: List[Either[String,Int]] = List(Left(Bad), Right(1))

scala> for (Left(x) <- l) yield x
res5: List[String] = List(Bad)

ここまでは順調ですね:

scala> l.map { case Left(x) => x }
<console>:13: warning: match is not exhaustive!
missing combination          Right

       l.map { case Left(x) => x }
             ^
scala.MatchError: Right(1)
    at $anonfun$1.apply(<console>:13)
    at ...

2 番目のバージョンが機能しないのはなぜですか? というか、最初のバージョンが機能するのはなぜですか?

4

3 に答える 3

4

-comprehensionでパターン マッチングを使用するforと、コンパイラは実際に への呼び出しを挿入filterinstanceOfmap.

編集:

また、セクション6.19には次のように書かれています:

g が単一のジェネレータ p <- e.withFilter((x1, ..., xn) => g ) に変換される場合、ジェネレータ p <- e の後にガードが続きます。ただし、x1、...、xn は自由変数です。 pの。

ジェネレーターは、以前に次のように定義されています。

Generator ::= Pattern1 '<-' Expr [ガード]

バイトコードを調べると、 への呼び出しfilterの前に への呼び出しが表示されmapます。

于 2010-07-27T14:13:46.273 に答える
2

Eastsunの発言への追加として:Scala 2.8にはcollectメソッドがあり、これはあなたの例で機能します:

l.collect { case Left(x) => x }
//--> List[String] = List(Bad)
于 2010-07-27T15:07:49.880 に答える
1

Scala 2.7 言語仕様、83 ページ、下から 2 番目の段落 (ここには 2.8 仕様はありません)。ジェネレータ パターン マッチング用のフィルタを挿入することは、理解のための翻訳プロセスの最初のステップです。

最後に確認したとき、これは型付きパターンでは機能しませんでした。これは驚くべきことです。だからあなたの例では

for(x:Left <- l) yield x  

型エラーをスローして動作しません

于 2010-07-27T14:39:49.330 に答える