なぜこのようなscala.Option
メソッドfold
が定義されていないのだろうか:
fold(ifSome: A => B , ifNone: => B)
に相当
map(ifSome).getOrElse(ifNone)
map
+を使用するよりも良いことはありませんgetOrElse
か?
なぜこのようなscala.Option
メソッドfold
が定義されていないのだろうか:
fold(ifSome: A => B , ifNone: => B)
に相当
map(ifSome).getOrElse(ifNone)
map
+を使用するよりも良いことはありませんgetOrElse
か?
私は個人的に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
}
いつものように、追加の抽象化があなたに利益を与えず、逆効果になるという限界があります。
ついに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]
ことについて不平を言います。代わりに、次のいずれかが必要ですf
Nil.type
x.fold[List[A]](Nil)(_ :: Nil)
x.fold(Nil: List[A])(_ :: Nil)
これはfold
、対応するとはまったく同等ではありませんmatch
。
できるよ:
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 で十分な場合が多くあります。特に、多くのmap
s をチェーンする可能性がある場合はそうです。(もちろん、関数合成で s をチェーンすることもできますがfun
、関数合成と値変換のどちらに注目するかによって異なります。)
Debilski が述べたように、Scalaz のOptionW.cata
orを使用できます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 }
実際、これはすべての代数的データ構造にあると便利です。