私はこのようなものから始めました:
def nonEmpty[A] = (msg: String) => (a: Option[A]) => a.toSuccess(msg)
val postal: Option[String] = request.param("postal")
val country: Option[String] = request.param("country")
val params =
(postal |> nonEmpty[String]("no postal" )).toValidationNel |@|
(country |> nonEmpty[String]("no country")).toValidationNel
params { (postal, country) => ... }
.toValidateNel
ここで、ボイラープレートを減らして読みやすくし、より多くのジュニア チーム メンバーに何を|@|
意味するかを説明する必要がないようにするとよいと思いました。最初に考えたList
のは、最後の行が機能しなくなり、静的な安全性をあきらめなければならないということでした。だから私はシェイプレスに目を向けました:
import shapeless._; import poly._; import syntax.std.tuple._
val params = (
postal |> nonEmpty[String]("no postal"),
country |> nonEmpty[String]("no country")
)
params.map(_.toValidatioNel).reduce(_ |@| _)
.map(...)
しかし、私はそのビットを乗り越えることさえできないようです. #scalaz の提案に従って試してみました:
type Va[+A] = Validation[String, A]
type VaNel[+A] = ValidationNel[String, A]
params.map(new (Va ~> VaNel) { def apply[T](x: Va[T]) = x.toValidationNel })
...無駄に。
私は #scalaz で助けを求めましたが、人々が箱から出してすぐに答えられるものではないようです。しかし、私は実用的な目的と学習目的の両方でこれを解決する方法を学びたいと思っています。
Kleisli[Va, A, B]
PS実際には、私の検証はを使用して個々の検証ステップを構成できるようにラップされていますが、到達>=>
するまでに問題に直交しているように見えます..map(...)
Kleisli
Validation[String, A]