scalaz を使用すると、Option を折りたたむことができます
b fold ( sb => A(sb) map (bb => C(i, some(bb))), C(i, none).success)
ポイントフリー スタイルsb => A(sb) map (bb => C(i, some(bb)))
の使用を単純化する方法はおそらくありますが、これはしばしば scala では見苦しくなります。
設定
scala> :paste
// Entering paste mode (ctrl-D to finish)
object A {
def apply(b: B): ValidationNEL[String, A] = sys.error("")
}
case class A()
case class B()
case class C(i: Int, a: Option[A])
// Exiting paste mode, now interpreting.
defined module A
defined class A
defined class B
defined class C
最初の実装
scala> def apply(i: Int, b: Option[B]): ValidationNEL[String, C] =
| b fold ( sb => A(sb) map (bb => C(i, some(bb))), C(i, none).success)
apply: (i: Int, b: Option[B])scalaz.Scalaz.ValidationNEL[String,C]
2 番目の実装
ファーストクラスの関数を宣言すると、合成の可能性が高くなります。例えば:
object A { val fromB: B => ValidationNEL[String, A] = _ => sys.error("") }
object C { val fromA: Int => A => C = i => a => C(i, some(a)) }
defined module A
defined module C
それで
scala> def apply(i: Int, b: Option[B]): ValidationNEL[String, C] =
| b fold (A.fromB andThen (_ map C.fromA(i)), C(i, none).success)
apply: (i: Int, b: Option[B])scalaz.Scalaz.ValidationNEL[String,C]