4

Option[Problem] がある場合は Option[Problem] を返し、検証の問題が見つからない場合は None を返す一連の検証関数があります。各検証関数を呼び出して停止し、None 以外の最初の結果を返す単純な関数を書きたいと思います。

当然、このメソッドを「Java スタイル」で記述できますが、より良いアプローチが存在するかどうかを知りたいです。

編集

これは元の Java ソリューションでした。

validate01(arg);
validate02(arg);
validate03(arg);
...

問題が発生した場合、各メソッドは例外をスローします。Scala を書いている間は、例外を避けていました。

4

3 に答える 3

6

例として、 a を検証したいとしましょうString。検証関数はと からまでStringの関数であるバリデータのリストを取ります。次のような機能的な方法で実装できます。StringOption[Problem]

def firstProblem(validators: List[String => Option[Problem]], s:String) =
  validators.view.flatMap(_(s)).headOption

これは、各検証関数を文字列に適用し、それがSome. 次に、この List の最初の要素を取得します。への呼び出しのためview、リストは必要な場合にのみ計算されます。したがって、最初の問題が見つかるとすぐに、それ以上のバリデータは呼び出されません。

于 2012-12-26T22:05:03.133 に答える
6

コンパイル時の検証回数が有限で既知の場合は、Options で .orElse を使用できます。

def foo(x: Int): Option[Problem] = ...
def bar(x: Int): Option[Problem] = ...
...
def baz(x: Int): Option[Problem] = ...


foo(1) orElse bar(2) orElse .. baz(n)
于 2012-12-26T22:06:04.533 に答える
1

多分あなたが望むでしょう-検証関数が引数を取らないと仮定して

def firstProblem(fs: (() => Option[Problem])*) = {
  fs.iterator.map(f => f()).find(_.isDefined).flatten
}

Option[Problem]既存のものがある場合、またはNoneそれらがすべて成功した場合は、既存のものを取得します。関数に引数を渡す必要がある場合は、それらの引数が何であるかを説明する必要があります。たとえば、次のことができます。

def firstProblem[A](a: A)(fs: (A => Option[Problem])*) = /* TODO */

それらすべてに同じ引数を渡すことができれば。次のように使用します。

firstProblem(myData)(
  validatorA,
  validatorB,
  validatorC,
  validatorD
)
于 2012-12-26T22:08:33.717 に答える