I started out with something like this:
def nonEmpty[A] = (msg: String) => (a: Option[A]) => a.toSuccess(msg)
val postal: Option[String] = request.param(\
Here's what this would look like with shapeless-contrib's 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")
)
And then:
object ToVNS extends Poly1 {
implicit def validation[T] = at[Validation[String, T]](_.toValidationNel)
}
val result = traverse(params.productElements)(ToVNS).map(_.tupled)
Now result
is a ValidationNel[String, (String, String)]
, and you can do anything with it that you could do with the awful ApplicativeBuilder
thing you'd get from reducing with |@|
.