Code snippets used in blog post "Composing Future, List and Either": https://pbassiner.github.io/blog/composing_future,_list_and_either.html
Last active
April 19, 2017 20:06
-
-
Save pbassiner/6bb41c132da822cce2020827d6163cc9 to your computer and use it in GitHub Desktop.
Blog Post - Composing Future. List and Either: code snippets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def getCommitsWithAuthor(): Future[Either[Error, List[CommitAndAuthor]]] = ??? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Transformer for `Either`, allowing the effect of an arbitrary type constructor `F` to be combined with the | |
* fail-fast effect of `Either`. | |
* | |
* `EitherT[F, A, B]` wraps a value of type `F[Either[A, B]]`. An `F[C]` can be lifted in to `EitherT[F, A, C]` via `EitherT.right`, | |
* and lifted in to a `EitherT[F, C, B]` via `EitherT.left`. | |
*/ | |
final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { | |
... | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def getCommitsWithAuthor(): Future[Either[Error, List[CommitAndAuthor]]] = | |
getCommits() flatMap { | |
case Right(commits) => sequence(listCommitsAndAuthor(commits)) map { list => | |
list.foldLeft( | |
Right[Error, List[CommitAndAuthor]](List.empty).asInstanceOf[Either[Error, List[CommitAndAuthor]]] | |
)( | |
(acc, x) => x match { | |
case Right(value) => acc.map(list => list :+ value) | |
case Left(err) => acc.left.map(_ => err) | |
} | |
) | |
} | |
case Left(e) => Future.successful(Left(e)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def getCommitsWithAuthor(): Future[Either[Error, List[CommitAndAuthor]]] = | |
getCommits() flatMap { | |
case Right(commits) => sequence( | |
commits => | |
commits map { commit => | |
getAuthor(commit.id) map { either => | |
either map { author => | |
CommitAndAuthor(commit, author) | |
} | |
} | |
} | |
) map { list => | |
list.foldLeft( | |
Right[Error, List[CommitAndAuthor]](List.empty).asInstanceOf[Either[Error, List[CommitAndAuthor]]] | |
)( | |
(acc, x) => x match { | |
case Right(value) => acc.map(list => list :+ value) | |
case Left(err) => acc.left.map(_ => err) | |
} | |
) | |
} | |
case Left(e) => Future.successful(Left(e)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sequence(listCommitsAndAuthor(commits)) map { list => | |
list.foldLeft( | |
Right[Error, List[CommitAndAuthor]](List.empty).asInstanceOf[Either[Error, List[CommitAndAuthor]]] | |
)( | |
(acc, x) => x match { | |
case Right(value) => acc.map(list => list :+ value) | |
case Left(err) => acc.left.map(_ => err) | |
} | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def listCommitsAndAuthor: List[Commit] => List[Future[Either[Error, CommitAndAuthor]]] = | |
commits => | |
commits map { commit => | |
getAuthor(commit.id) map { either => | |
either map { author => | |
CommitAndAuthor(commit, author) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sequence(listCommitsAndAuthor(commits)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def getCommits(): Future[Either[Error, List[Commit]]] | |
def getAuthor(commitId: String): Future[Either[Error, Author]] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
final case class Commit(id: String) | |
final case class Author(id: String) | |
final case class CommitAndAuthor(commit: Commit, author: Author) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cats.data.EitherT | |
import cats.instances.future._ | |
import cats.instances.list._ | |
import cats.syntax.traverse._ | |
def getCommitsWithAuthor(): Future[Either[Error, List[CommitAndAuthor]]] = | |
(for { | |
commits <- EitherT(getCommits()) | |
result <- commits.map { commit => | |
EitherT(getAuthor(commit.id)) map { author => CommitAndAuthor(commit, author) } | |
}.sequenceU | |
} yield result).value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cats.data.EitherT | |
import cats.instances.future._ | |
implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global | |
commits.map { commit => | |
EitherT(getAuthor(commit.id)) map { author => CommitAndAuthor(commit, author) } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cats.data.EitherT | |
import cats.instances.list._ | |
import cats.instances.future._ | |
import cats.syntax.traverse._ | |
implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global | |
commits.map { commit => | |
EitherT(getAuthor(commit.id)) map { author => CommitAndAuthor(commit, author) } | |
}.sequenceU |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment