Each is a macro library that converts native imperative syntax to scalaz's monadic expression.
I am the author of Stateless Future, which is macro library that provide await
for asynchronous programming.
await
is a mechanism that transform synchronous-like code into asynchronous expressions. C# 4.5, ECMAScript 7 and Python 3.5 also support the mechanism.
I implemented the await
mechanism in Stateless Future in an algorithm called CPS transform. When I learn scalaz, I found that the same algorithm could be applied for any monadic expression, including Option
monad, IO
monad, and Future
monad. So I started this project, Each.
Each is a superset of await
syntax, as Each support multiple types of monads, while await
only works with Future
. When we perform a CPS transform for monadic expression with the Future
monad, the use case looks almost the same with the await
syntax in Stateless Future
For example:
import com.thoughtworks.each.Monadic._
import scalaz.std.scalaFuture._
// Returns a Future of the sum of the length of each string in each parameter Future,
// without blocking any thread.
def concat(future1: Future[String], future2: Future[String]): Future[Int] = monadic[Future] {
future1.each.length + future2.each.length
}
The similar code may work for other monads:
import com.thoughtworks.each.Monadic._
import scalaz.std.option._
def plusOne(intOption: Option[Int]) = monadic[Option] {
intOption.each + 1
}
assertEquals(None, plusOne(None))
assertEquals(Some(16), plusOne(Some(15)))
import com.thoughtworks.each.Monadic._
import scalaz.std.list._
def plusOne(intSeq: List[Int]) = monadic[List] {
intSeq.each + 1
}
assertEquals(Nil, plusOne(Nil))
assertEquals(List(16), plusOne(List(15)))
assertEquals(List(16, -1, 10), plusOne(List(15, -2, 9)))
libraryDependencies += "com.thoughtworks.each" %% "each" % "0.2.0"
import com.thoughtworks.each.Monadic._
Scalaz has provided Option
monad, you just import it.
import com.thoughtworks.each.Monadic._
import scalaz.std.option._
Please import other monad instances if you need other monad.
import com.thoughtworks.each.Monadic._
import scalaz.std.option._
val Option[String] = monadic[Option]
5FBE
{
"Hello, Each!"
}
import com.thoughtworks.each.Monadic._
import scalaz.std.option._
val name = Option("Each")
val Option[String] = monadic[Option] {
"Hello, " + name.each + "!"
}