6

ビルダーパターンを使用して構築されたオブジェクトを想定しましょう。

このビルダーパターンには、buildフィールドの検証とターゲットタイプへの変換に焦点を当てたメソッドが含まれます。

この検証は、以下を使用して実装できます。

  • Either[FailureObject, TargetObject]タイプ
  • Try[TargetObject](Scala 2.10の新機能)
  • Validation[FailureObject, TargetObject]またはValidationNEL[FailureObject, TargetObject]scalazライブラリから

ValidationオーバーEitherタイプの主な利点の1つは、Validation「箱から出して」障害を蓄積できることです。

しかし、「新しい」Try方法はどうでしょうか。Try箱から出してすぐに使える「モナディック」メソッドもあることに気づきました。たとえばmap、 。flatMapの助けを借りずにどちらのタイプでも本当に欠けていたものですProjection

Try[FieldType]したがって、各フィールド検証メソッドがaを返し、より正確には、障害が発生した場合にTry[SpecificFieldExceptionType];を返すことを想像します。このネストされたものStringには、メソッド全体で蓄積できるメッセージフィールドとrootCauseフィールドが含まれていますbuild

Scala 2.10を使用して、Tryビルダーパターンのような単純な検証のためにscalaz検証ライブラリを置き換える練習をすることができますか?

**編集****

Tryソースコードを読み取ることにより、Tryいくつかの例外を蓄積できないように聞こえ、したがってフェイルファストに向けられます。Try.flatMap潜在的な以前の失敗を返すことさえあるので、蓄積の概念がありません:

def flatMap[U](f: T => Try[U]): Try[U] = this.asInstanceOf[Try[U]]

それどころか、ValidationNEL蓄積機能を処理します。

確認はありますか?

4

1 に答える 1

11

トレードオフがあります:

  • scalaz.ValidationインスタンスをE指定すると、タイプのエラーを累積できます。これは、次のようなSemigroup[E]ものとして使用することを目的としています。Applicative

    (fragileFoo |@| fragileBar) { case (foo, bar) => doSomething(foo, bar) }
    

    それは側面に偏った方法を持っているmapので、あなたはそれを理解の中で便利に使うことができます。ただし、インスタンスが定義されていないため、高次のものでは使用できません(たとえば、モナド変換子では使用できません)。ただし、この欠点は問題にはならないようです。flatMapSuccessforMonad

  • scalaz.\/、あなたが言及しなかったが、Monad(再び、側に偏ったRight)を形成します。ただし、として使用するとApplicative、障害が蓄積されることはありませんValidation

  • util.Tryに似ておりscalaz.\/、に特化していThrowableます。ここでもエラーの蓄積はありませんが、エラー回復の概念があります。ただし、「ビルダーパターン」のユースケースでは、これはそれほど役に立たないようです。

  • 最後にutil.Either、他の3つのオプションと比較して、検討する価値はありません。どちらか一方に偏っていないため、モナディックなことをするたびに、明示的かつ一貫してleftまたは投影を要求する必要があります。right

私の最善の推測は、あなたの状況にとって、scalaz.Validationが最も適切な選択であるということです。

于 2013-04-30T05:15:52.327 に答える