Validationから値を取り出すイディオムです。
前回は、Validationに格納されている成功(Success)の値を取り出すイディオムでした。失敗(Failure)の場合はデフォルト値を使いました。
今回は、Validationに格納されている成功(Success)と失敗(Failure)を同じ型の値に変換して取り出すイディオムです。
Validation[Throwable, Int]に対して、Successの場合はSuccessの値(Int)をStringに、Failureの場合はFailureの値ThrowableをStringにして返す処理を考えます。SuccessのIntをStringに、FailureのThrowableをStringに変換する関数は外部から与えることにします。
(分類の基準)
Java風
if式でValidation#isSuccessメソッドを使ってSuccessとFailureの判定をして、処理を切り分ける事ができます。SuccessとFailureの値を取り出し、適切な関数を適用します。SuccessとFailureのいずれもasInstanceOfが必要になるので、あまり使いたくない用法です。
def f(a: Validation[Throwable, Int], g: Throwable => String, h: Int => String): String = { if (a.isSuccess) { h(a.asInstanceOf[Success[Throwable, Int]].a) } else { g(a.asInstanceOf[Failure[Throwable, Int]].e) } }
Scala風
match式を使うとSuccessとFailureのパターンマッチングで書くことができます。
def f(a: Validation[Throwable, Int], g: Throwable => String, h: Int => String): String = { a match { case Success(s) => h(s) case Failure(e) => g(e) } }
Scala
ValidationはScalazの機能なので、「Scala」というのは変ですが、foldメソッドを用いるのがScala流のコーディングです。Validationのfoldメソッドは、第一引数にFailureの値を変換する関数、第二引数にSuccessの値を変換する関数を指定します。
def f(a: Validation[Throwable, Int], g: Throwable => String, h: Int => String): String = { a.fold(g, h) }
Scalaz
foldメソッドを使う方式は「Scala」のところで紹介しました。その他に、Scalazらしい特徴的な方式はないと思います。
ノート
取り出す値の型がSuccessの値の型が同じ場合には、「|||」メソッドを使うことができます。
Validationの「|||」メソッドは、Successの場合は値の取り出し、Failureの場合は指定したFailureの値を関数で変換して取り出す関数です。
def f(a: Validation[Throwable, Int], g: Throwable => Int): Int = { a ||| g }
また、foldメソッドも第二引数(Successの場合に適用する関数)を省略して、以下のような使い方ができます。
def f(a: Validation[Throwable, Int], g: Throwable => Int): Int = { a.fold(g) }
諸元
- Scala 2.9.2
- Scalaz 6.0.4
0 件のコメント:
コメントを投稿