Могу ли я использовать преобразователи монад, чтобы упростить эту композицию?

предположим, что у меня есть

type VS[A] = Validation[String, A]

val v: VS[Option[A]]
val f: A => VS[B]

Я хочу получить результат типа VS[Option[B]], но если vявляется Success(None), результат также должен быть Успех(Нет). Вот пример:

scala> val v: VS[Option[String]] = some("4.5").success
v: VS[Option[String]] = Success(Some(4.5))

scala> val f = (s : String) => (try { s.toInt.success } catch { case x => x.getMessage.fail }): VS[Int]
f: String => VS[Int] = <function1>

Тогда:

scala> import Validation.Monad._
import Validation.Monad._

scala> (v map2 f map (_.sequence)).join
res4: scalaz.Validation[String,Option[Int]] = Failure(For input string: "4.5")

Случай успеха:

scala> val v: VS[Option[String]]= some("5").success
v: VS[Option[String]] = Success(Some(5))

scala> (v map2 f map (_.sequence)).join //UGLY composition
res7: scalaz.Validation[String,Option[Int]] = Success(Some(5))

И пустой случай:

scala> val v: VS[Option[String]]= none[String].success
v: VS[Option[String]] = Success(None)

scala> (v map2 f map (_.sequence)).join
res6: scalaz.Validation[String,Option[Int]] = Success(None)

Есть ли «более приятный» способ сделать это (возможно, с использованием композиции клейсли или преобразователей монад)?

6
задан oxbow_lakes 1 June 2012 в 16:08
поделиться