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 件のコメント:
コメントを投稿