Кошки: сопоставление кортежей с тем же аппликативным - PullRequest
4 голосов
/ 10 апреля 2019

Допустим, у меня есть:

val x1: Either[String, Int] = Right(1)
val x2: Either[String, Float] = Left("Nope")
val x3: Either[String, Double] = Left("Not Today")

Я хочу объединить их вместе и получить Either[NonEmptyList[String], (Int, Float, Double)]. Для этого я сейчас делаю следующее:

import cats.syntax.all._
(
  x1.toValidatedNel,
  x2.toValidatedNel,
  x3.toValidatedNel
).tupled
 .toEither

Что делает работу, но немного утомительно. Есть ли способ сделать это, позвонив toValidatedNel только один раз? что-то вроде:

(x1, x2, x3)
  .fooMap(_.toValidatedNel)
  .tupled
  .toEither

Существует ли такой fooMap где-нибудь у кошек? или нам нужно HLists для этого?

1 Ответ

3 голосов
/ 10 апреля 2019

Используя Shapeless, это

import shapeless.syntax.std.tuple._
object toValidatedNel extends Poly1 {
  implicit def cse[A, B, AA >: A]: Case.Aux[Either[A, B], ValidatedNel[AA, B]] = at(_.toValidatedNel[AA])
}

(x1, x2, x3)
  .map(toValidatedNel)
  .tupled
  .toEither
...