7

私はこのようなものから始めました:

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(...)KleisliValidation[String, A]

4

1 に答える 1

3

これはshapeless-contribでどのように見えるかですtraverse:

import scalaz._, Scalaz._
import shapeless._, contrib.scalaz._, syntax.std.tuple._

def nonEmpty[A] = (msg: String) => (a: Option[A]) => a.toSuccess(msg)

val postal: Option[String] = Some("00000")
val country: Option[String] = Some("us")

val params = (
  postal  |> nonEmpty[String]("no postal"),
  country |> nonEmpty[String]("no country")
)

その後:

object ToVNS extends Poly1 {
  implicit def validation[T] = at[Validation[String, T]](_.toValidationNel)
}

val result = traverse(params.productElements)(ToVNS).map(_.tupled)

resultは であり、で還元することで得られるValidationNel[String, (String, String)]ひどいものでできることは何でもできます。ApplicativeBuilder|@|

于 2014-10-16T23:21:12.437 に答える