Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
7 Commits
 
 
 
 
 
 

Repository files navigation

Archived project

FutureOps

This is a port of Hamsters FutureOps to Scala 2.13. .
Update June 2026: Hamsters full lib is now compatible with Scala 3 and 2.13

Goal

Monad stacks are not easy to compose (e.g. in a for comprehension), and if you don't want to use Monad transformers you can use this Future additional methods.

FutureOps.fromEither

import io.github.hamsters.FutureOps

FutureOps.fromEither(Right("a")) //Future("a")
FutureOps.fromEither(Left(BoomError)) //Future(BoomError)

squash Future[Either[Throwable, A]] and Future[Try[A]]

You can use squash on a Future[Either[Throwable, A]] to get a Future[A].

import FutureOps._

abstract class Error(message: String) extends Exception(message)
case object BoomError extends Error("Boom")

val fea: Future[Either[Error, String]] = Future(Right("a"))
val feb: Future[Either[Error, String]] = Future(Left(BoomError))

fea.squash //Future("a")
feb.squash //Future(BoomError)

You can also squash on a Future[Try[A]] to get a Future[A] in much the same way:

import FutureOps._

val fta: Future[Try[String]] = Future(Success("a"))
val ftb: Future[Try[String]] = Future(Failure(new Exception("Boom")))

fta.squash //Future("a")
ftb.squash //Future(Exception("Boom"))

It can also be useful to compose several Future[Either[Throwable, _]] without monad transformers :

def fea: Future[Either[Throwable, Int]] = Future(Right(1))
def feb(a: Int): Future[Either[Throwable, Int]] = Future(Right(a + 2))

val composedAB: Future[Int] = for {
  a <- fea.squash
  ab <- feb(a).squash
} yield ab

composedAB // Future("ab")

val error: Either[Throwable, Int] = Left(BoomError)
val composedABWithError: Future[Int] = for {
  a <- Future.successful(error).squash
  ab <- feb(a).squash
} yield ab

composedABWithError //Future(Failure(BoomError))

Composing several Future[Try[_]]s without monad transformers is also possible:

def fta: Future[Try[Int]] = Future(Success(1))
def ftb(a: Int): Future[Try[Int]] = Future(Success(a + 2))

val composedAB: Future[Int] = for {
  a <- fta.squash
  ab <- ftb(a).squash
} yield ab

composedAB // Future("ab")

Options

Same operations can be used with options : FutureOps.fromOption and squash on Future[Option[A]]. For empty options, an EmptyValueError will be raised.

Install

Add this to you build.sbt :

resolvers += Resolver.bintrayRepo("loicdescotte", "Hamsters") 
libraryDependencies += "io.github.scala-hamsters" %% "future-ops" % "1.0.0"

About

Operations to ease programming with Future

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.