2

Option クラスのドキュメントでは、次の 2 つの例は同等であると書かれています。

val name: Option[String] = request getParameter "name"
val upper = name map { _.trim } filter { _.length != 0 } map { _.toUpperCase }
println(upper getOrElse "")

val upper = for {
  name <- request getParameter "name"
  trimmed <- Some(name.trim)
  upper <- Some(trimmed.toUpperCase) if trimmed.length != 0
} yield upper
println(upper getOrElse "")

しかし、それらがどのように同等であるかがわかりません。最初のコード ブロックrequest getParameter "name"では type のインスタンスを返しますOption[String]が、2 番目のコード ブロック ステートメントname <- request getParameter "name"では type のインスタンスを返しますString(次のステートメントがvariable (に対して定義されていないため) のtrimメソッドを呼び出すためと仮定しました)。nametrimOption[String]

4

2 に答える 2

5

for ... yield内包表記からmap/メソッド呼び出しへの変換flatMapは、コンパイラーによって行われます。OptionIterable;である必要はありません。この場合に必要なのはOption/mapメソッドflatMapだけです:

  • flatMap同じブロック内でその後にさらに->呼び出しがある場合for
  • mapそれが最後なら

次のように独自のMyOptionクラスを作成できます。

case class MyOption[+T](value: T) {
  def flatMap[A](f: T => MyOption[A]): MyOption[A] = f(value)
  def map[A](f: T => A): MyOption[A] = MyOption(f(value))
  override def toString = s"Some($value)"
}

それで:

val result = for {
  a <- MyOption("one")
  b <- MyOption("two")
} yield a + "," + b
println(result)
// prints: Some(one,two)
于 2013-05-12T01:30:54.073 に答える
1

OptionIterable(コンパニオンオブジェクトに暗黙的option2Iterableなメソッドがあります)、それが句Optionで使用できる理由です。someVar <- someOption実際、その矢印は「右側のコレクションから要素を取得する」ことを意味します。

そうですname、2番目の例ではString.

map最初のものでは、 で使用されているおよび他のIterableメソッドがあることがわかりますOption。これは基本的に以下の式と同じですforが、メソッドを直接呼び出しますが、 whileforは単なる構文糖衣であり、コンパイラによってメソッド呼び出しのチェーンに変換されます。

于 2013-05-11T19:38:38.313 に答える