質問

なぜだろうか scala.Option 方法がありません fold この定義のように:

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

に相当

map(ifSome).getOrElse(ifNone)

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

役に立ちましたか?

解決

できるよ:

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

また

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

(両方のソリューションが評価されます els 価値によって、それはあなたが望むものではないかもしれません。ありがとう レックス・カー それを指摘してください。)

編集:

しかし、あなたが本当に欲しいのはScalazのものです カタルフィズム cata (基本的にa fold これは単に処理するだけではありません Some 値だけでなく、マップします None あなたが説明したことです)

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がそれを表現する「より自然な」方法である場合にのみ使用する必要があることに注意する必要があります。単純な場合がたくさんあります mapgetOrElse 特にそれが潜在的にたくさんのチェンをすることを伴う場合は十分です maps。 (ただし、チェーンすることもできます funもちろん、関数の構成を伴う - それは、関数の構成に焦点を合わせるか、値変換に焦点を合わせるかによって異なります。

他のヒント

私は個人的にのような方法を見つけます 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
}

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

最終的に追加されました Scala 2.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. 。代わりに、1つが必要です

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

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

Debilskiが述べたように、Scalazを使用できます OptionW.cata また fold. 。ジェイソンがコメントしたように、名前付きパラメーターはこれを見栄えを良くします:

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 }

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top