Liste von scalaz.Validation kartieren und verkleinern / überklappen

Ich habe mit so etwas angefangen:

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) => ... }

Nun dachte ich, es wäre schön, das Boilerplate zu verkleinern, um die Lesbarkeit zu verbessern und um nicht mehr Junior-Teammitgliedern erklären zu müssen, was.toValidateNel und|@| bedeuten. Der erste Gedanke warList aber dann würde die letzte Zeile nicht mehr funktionieren und ich müsste auf statische Sicherheit verzichten. Also schaute ich zu Shapeless:

import shapeless._; import poly._; import syntax.std.tuple._

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

params.map(_.toValidatioNel).reduce(_ |@| _)

jedoch, ich kann nicht einmal scheinen, an dem @ vorbei zu komm.map(...) bisschen. Ich habe nach einem Vorschlag auf #scalaz versucht:

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 })

...umsonst

Ich habe bei #scalaz um Hilfe gebeten, aber es scheint nicht so, als hätten die Leute eine Out-of-the-Box-Antwort auf diese Frage. Ich bin jedoch sehr daran interessiert zu lernen, wie dies sowohl für praktische als auch für Lernzwecke gelöst werden kann.

P.S. In Wirklichkeit sind meine Validierungen in @ verpackKleisli[Va, A, B], damit ich mit @ einzelne Validierungsschritte zusammenstellen ka>=> aber das scheint orthogonal zum Thema zu sein, als zu dem Zeitpunkt, dass.map(...) ist erreicht, alleKleislis wird auf @ "reduziert&quoValidation[String, A].

Antworten auf die Frage(1)

Ihre Antwort auf die Frage