Ho iniziato con qualcosa di simile:Mappa e ridurre/fold over HList di scalaz.Validation
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) => ... }
Ora ho pensato che sarebbe stato bello per ridurre il boilerplate per una migliore leggibilità e per non dover spiegare a più membri della squadra junior cosa significa .toValidateNel
e |@|
. Il primo pensiero è stato List
ma poi l'ultima riga avrebbe smesso di funzionare e avrei dovuto rinunciare alla sicurezza statica. Così ho guardato verso informe:
import shapeless._; import poly._; import syntax.std.tuple._
val params = (
postal |> nonEmpty[String]("no postal"),
country |> nonEmpty[String]("no country")
)
params.map(_.toValidatioNel).reduce(_ |@| _)
tuttavia, non riesco nemmeno a superare il bit .map(...)
. Ho provato come suggerimento su #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 })
... inutilmente.
Ho chiesto aiuto su #scalaz ma non sembra che la gente abbia una risposta immediata. Tuttavia, sono davvero entusiasta di imparare come risolvere questo problema sia a livello pratico che di apprendimento.
P.S. in realtà le mie convalide sono racchiuse all'interno di in modo da poter comporre singole fasi di convalida utilizzando >=>
ma che sembra essere ortogonale al problema in quanto dal momento in cui è stato raggiunto .map(...)
, tutti gli Kleisli
s saranno stati "ridotti" a Validation[String, A]
.
Avrete sicuramente bisogno di definire il 'Poly1' come un oggetto (per varie strane ragioni correlate a Scala che hanno a che fare con identificatori stabili). Questo assomiglia molto ad un traversal, e la 'traverse' di shapeless-contrib ti permetterebbe di fare il' toValidationNel' e (l'equivalente morale di) 'riduci (_ | @ | _)' in un solo passaggio. –
Vedere anche il mio blog post vagamente correlato [qui] (http://meta.plasm.us/posts/2013/06/05/applicative-validation-syntax/). –