Карта и уменьшить / сложить HList of 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) => ... }
Теперь я подумал, что было бы неплохо уменьшить шаблон для лучшей читабельности и отсутствия необходимости объяснять более младшим членам команды, что.toValidateNel
а также|@|
имею в виду. Первая мысль былаList
но тогда последняя строка перестала бы работать, и мне пришлось бы отказаться от некоторой статической безопасности. Итак, я посмотрел в сторону 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(_ |@| _)
тем не менее, я даже не могу пройти.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]
чтобы я мог составить отдельные шаги проверки, используя>=>
но это кажется ортогональным к вопросу, как к тому времени, когда.map(...)
достигнуто, всеKleisli
s будет "уменьшен" доValidation[String, A]
.