Skip to content

Instantly share code, notes, and snippets.

@ponkotuy
Created July 11, 2019 09:14
Show Gist options
  • Save ponkotuy/4c67ed1d3857ce06548236675cc5a721 to your computer and use it in GitHub Desktop.
Save ponkotuy/4c67ed1d3857ce06548236675cc5a721 to your computer and use it in GitHub Desktop.
EitherT[Future, A, B]のUtil
import cats.data.EitherT
import cats.implicits._
import scala.collection.immutable.Iterable
import scala.concurrent.{ExecutionContext, Future}
object EitherTFutureUtils {
def eitherT[A, B](a: A): EitherT[Future, B, A] = EitherT(Future.successful(Either.right[B, A](a)))
def futureReduceLeft[A, B](xs: Iterable[EitherT[Future, B, A]])(f: (A, A) => A)(implicit ec: ExecutionContext): EitherT[Future, B, A] = {
val result = Future.reduceLeft(xs.map(_.value)) { case (orig, x) =>
for {
a <- orig
b <- x
} yield f(a, b)
}
EitherT(result)
}
def sequence[A, B](xs: Iterable[EitherT[Future, B, A]])(implicit ec: ExecutionContext): EitherT[Future, B, List[A]] = {
val future = Future.sequence(xs.map(_.value)).map {
_.foldLeft[Either[B, List[A]]](Right(Nil)) {
case (Left(b), _) => Left(b)
case (Right(_), Left(b)) => Left(b)
case (Right(list), Right(a)) => Right(a :: list)
}.map(_.reverse)
}
EitherT(future)
}
}
@taisukeoe
Copy link

taisukeoe commented Jul 11, 2019

よく考えたら、futureReduceLeftの実装でTraverse#sequenceは不要でした。foldだけで実装できますね。
というわけでもっと簡単になります。

import cats._
import cats.instances.all._

def futureReduceLeft[T[_]: Foldable, A: Monoid, B](xs: T[EitherT[Future, B, A]])(implicit ec: ExecutionContext): EitherT[Future, B, A] = xs.fold

Monoid[A] から Monoid[EitherT[Future, B, A]] を導出できるのが理由です。以下参照。

https://github.com/typelevel/cats/blob/07b2c215fb6830dd909674abee8ce832f9af605b/core/src/main/scala/cats/data/EitherT.scala#L531-L532

https://github.com/typelevel/cats/blob/07b2c215fb6830dd909674abee8ce832f9af605b/core/src/main/scala/cats/instances/future.scala#L39-L40

https://github.com/typelevel/cats/blob/07b2c215fb6830dd909674abee8ce832f9af605b/kernel/src/main/scala/cats/kernel/instances/EitherInstances.scala#L23

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment