1

ScalaでOptionsを試してみているときに、この特有の問題に遭遇しました。

私は次のようにList[Option[Int]]を作成することから始めました。

scala> List(Some(1),Some(2),None,Some(3))
res0: List[Option[Int]] = List(Some(1), Some(2), None, Some(3))

次に、次のように、res0のリストのエントリに1への加算をマップしようとしました。

scala> res0 map (_ + 1)

これは私にエラーを与えました:

<console>:9: error: type mismatch;
 found   : Int(1)
 required: String
              res0 map (_ + 1)
                            ^

次に、次のようにエントリに追加をflatMappingしてみました。

scala> res0 flatMap (_ + 1)

これは私に同じエラーを与えました:

<console>:9: error: type mismatch;
 found   : Int(1)
 required: String
              res0 flatMap (_ + 1)
                                ^

しかし、次のようなres0.flatMap(r => r)結果でうまく機能します。

res9: List[Int] = List(1, 2, 3)

エントリを1に追加すると、mapとflatMapの両方で失敗する理由を誰かに教えてもらえますか?

4

6 に答える 6

6

にを追加しようとしているため、最初の2つのことは失敗しOptionましたがInt、それは不可能です。

奇妙なエラーメッセージは、ScalaがメソッドOptionを持っていないため、連結+を試みていると想定しているために発生しますが、に、またはをString追加する必要があり、どちらも実行していないため、エラーメッセージが表示されます。 。OptionStringStringOption

最後のケースでは、何も追加しようとはしていません。単にそのまま返さOptionれているため、エラーメッセージは表示されません。

于 2013-01-29T08:55:57.327 に答える
1

タイプが間違っていて、コンパイラーが正しくそのように述べているため、これらは失敗しています。

map関数を期待しているため、マップケースは失敗しますA => B。あなたのコードでは、それA => Bは実際Int => Intには機能しません。なぜならmap、あなたのリストを呼び出すことはそれAが実際に であるということを意味するからですOption[Int]

さらに、flatMap次の形式の関数を期待しますA => F[B]。だからあなたがやったらあなたはあなたの答えを得るでしょうres0 flatMap { o => o map { a => a + 1 } }。これは基本的に次の拡張です。

for {
  element <- res0 // o above
  value <- element // a above
} yield value + 1
于 2013-01-29T09:00:35.237 に答える
1

getを使用して値を抽出し、計算Some[Int]を可能にしてみてください。Intvalue + 1

res0 map{_.getOrElse(0) + 1}

@ Sepp2kで指摘されているように、代わりにを使用しcollectて、None

res0 collect {case Some(x) => x + 1 }
于 2013-01-29T08:47:54.610 に答える
1

でないすべての値をインクリメントするには、次のように、リストのNone各要素もマップする必要があります。Option

scala> res0.map(_.map(_ + 1))
res1: List[Option[Int]] = List(Some(2), Some(3), None, Some(4))

を除外したい場合Noneは、実際に:を使用しますflatMap

scala> res0.flatMap(_.map(_ + 1))
res2: List[Int] = List(2, 3, 4)
于 2013-01-29T08:53:34.233 に答える
1

に与えられた関数と、リストの要素タイプの値を取得するためにflatMap与えられた関数の両方(この場合は) 。ただし、関数は、ではなくを期待しているため、どちらかまたはこの場合の引数として使用することはできません。さらに、に与えられた関数はiterable¹を返す必要がありますが、関数は数値を返します。mapOption[Int]_ + 1IntOption[Int]mapflatMapflatMap

これはあなたが望むことをします:res0 flatMap (_ map (_ + 1))。ここで、に与えられた関数は、オプションを呼び出すことによってをflatMap取り、Option[Int]を返します。次に、関数によって返されたオプションを取得し、それらを連結します。Option[Int]mapflatMap

¹技術的にはGenTraversableOnce

于 2013-01-29T08:53:51.940 に答える
1

e.+(1)のすべての要素を呼び出そうとしますが、でe宣言された関数ではありません。ただし、文字列の連結は可能です(暗黙のfromからまでがあると仮定します)が、2番目の引数も文字列である場合に限ります(私が仮定した暗黙の存在がここで考慮されない理由はわかりません)。List[Option[Int]]+Option[_]AnyString

この問題を克服するには、@ korefnによって提案されたデフォルト値を使用するか、またはの別の呼び出しでの区別を「非表示」にしますSome(x)Nonemap

map(_.map(_ + 1))
于 2013-01-29T08:56:11.967 に答える