36

なぜこのようなscala.Optionメソッドfoldが定義されていないのだろうか:

fold(ifSome: A => B , ifNone: => B)

に相当

map(ifSome).getOrElse(ifNone)

map+を使用するよりも良いことはありませんgetOrElseか?

4

4 に答える 4

74

私は個人的にcata、引数がしばしばそれをやり過ぎているので、そのようなメソッドは2つのクロージャを取ると思います。map+よりも読みやすさが本当に向上しgetOrElseますか?あなたのコードの新参者について考えてみてください:彼らは何を作りますか

opt cata { x => x + 1, 0 }

あなたは本当にこれがより明確だと思いますか

opt map { x => x + 1 } getOrElse 0

実際、私はどちらも古き良き時代よりも好ましいと主張します

opt match {
  case Some(x) => x + 1
  case None => 0
}

いつものように、追加の抽象化があなたに利益を与えず、逆効果になるという限界があります。

于 2011-03-16T22:31:34.937 に答える
41

ついにScala2.10に署名付きで追加されましたfold[B](ifEmpty: => B)(f: A => B): B

残念ながら、これには一般的なマイナスの結果があります。引数Bのみに基づいて呼び出しに対して推測されますifEmptyが、実際にはより狭いことがよくあります。例(正しいバージョンはすでに標準ライブラリにあります。これはデモンストレーション用です)

 def toList[A](x: Option[A]) = x.fold(Nil)(_ :: Nil)

Scalaは、望まBれるNil.type代わりにあると推測し、戻ってこないList[A]ことについて不平を言います。代わりに、次のいずれかが必要ですfNil.type

 x.fold[List[A]](Nil)(_ :: Nil)
 x.fold(Nil: List[A])(_ :: Nil)

これはfold、対応するとはまったく同等ではありませんmatch

于 2013-02-02T14:22:22.620 に答える
25

できるよ:

opt foldLeft (els) ((x, y) => fun(x))

また

(els /: opt) ((x,y) => fun(x))

(両方のソリューションは値によって評価されますが、これはあなたが望むものではないかもしれません。指摘してくれた Rex Kerrels に感謝します。)

編集:

しかし、あなたが本当に欲しいのは、Scalaz のカタモルフィズム cata(基本的に、値foldを処理するだけでなく、部分をSomeマップするaNoneです。これはあなたが説明したものです)

opt.cata(fun, els)

次のように定義されます (ここvalueで pimped オプション値)

def cata[X](some: A => X, none: => X): X = value match {
  case None => none
  case Some(a) => some(a)
}

これは と同等opt.map(some).getOrElse(none)です。

ただし、「より自然な」表現方法である場合にのみ cata を使用する必要があることに注意してください。map単純な–<code>getOrElse で十分な場合が多くあります。特に、多くのmaps をチェーンする可能性がある場合はそうです。(もちろん、関数合成で s をチェーンすることもできますがfun、関数合成と値変換のどちらに注目するかによって異なります。)

于 2011-03-16T16:18:07.660 に答える
19

Debilski が述べたように、Scalaz のOptionW.cataorを使用できますfold。Jason がコメントしたように、名前付きパラメーターを使用すると見栄えがよくなります。

opt.fold { ifSome = _ + 1, ifNone = 0 }

Noneケースで必要な値がmzeroいくつかのものでMonoid[M]あり、ケースの関数f: A => MがあるSome場合は、これを行うことができます。

opt foldMap f

そう、

opt map (_ + 1) getOrElse 0

になる

opt foldMap (_ + 1)

個人的には、カタモルフィズムとなる方法がOption必要だと思います。applyそうすれば、これを行うことができます:

opt { _ + 1, 0 }

また

opt { some = _ + 1, none = 0 }

実際、これはすべての代数的データ構造にあると便利です。

于 2011-03-16T23:05:09.993 に答える