2016-02-16 36 views
5

ScalaZではOption[Validation[E, A]]Validation[E, Option[A]]に変換する慣用方法は何ですか?例えばオプション[検証[E、A]]を検証[E、オプション[A]]に変換する

、以下の仮定のコードで:

def convert(x: Option[Validation[E, A]]): Validation[E, Option[A]] =  
    /* ??? */ 

def validateThing(thing: A): Validation[E, A] = 
    /* whatever */ 

def exampleUseCase(maybeThing: Option[Thing]): Validation[E, Option[Thing]] = { 
    val validated: Option[Validation[E, Thing]] = a.map(validateThing(_)) 

    // ... 

    val result: Validation[E, Option[Thing]] = convert(validated) 
    result 
} 

convertの実装は、慣用的なScalaZのように何を見ますか?

+1

私はこの変換が私にはあまり意味がないと言います。 'maybeThing'が' None'ならば、どんな結果が期待できますか?おそらく検証に失敗したかもしれません。もしそれがnoneでなければ、値を抽出し、成功した場合には 'Option'は必要ありません。 – 4lex1v

+0

'validate'と' validateThing'は仮説ですが、そのような変換*が起こるかもしれない場所のコンテキストを表示するだけです。私は 'convert'の実装が何であるかだけに興味があります。 – kes

+0

しかし、 'maybeThing'が' None'のときに何を期待するかという特定の質問に答えるには、 'None'の検証に成功しました。 – kes

答えて

4

私はここで2つの解決策を見ることができます。おそらく引数、たとえば上のパターンマッチングを使用して最も簡単な1:

Scalazベースのソリューションについては
def convert[A](v: Option[Validation[Throwable, A]]): Validation[Throwable, Option[A]] = { 
    v match { 
    case None => Validation.success(None) 
    case Some(valid) => valid.map(Some(_)) 
    } 
} 

、私は、およそsequenceあなたが潜在的な問題を、あなたがすることができます集約する代わりに、検証のValidationNelを、使用する必要があり、このように考えていましたTraversableconvertを実装:検証は、2種類のパラメータを持っている原因

def convert[A](v: Option[ValidationNel[Throwable, A]]): ValidationNel[Throwable, Option[A]] = 
    Traverse[Option].sequenceU(v) 

私だけではなくsequencesequenceUを使用しています実際にそれを注意してください、それは、適切な型推論のための内部Scalazの魔法よりも何もありません。希望すると助けてくれる

+2

全てを読み込んだり、少なくとも 'std.option._'と' syntax.traverse._'を読み込んだら 'c.sequenceU'を書くことができます。 –

関連する問題