Skip to content

Instantly share code, notes, and snippets.

@orium
Last active September 26, 2018 13:26
Show Gist options
  • Save orium/b9124eafc5b0e5a536b38a1b46f5718c to your computer and use it in GitHub Desktop.
Save orium/b9124eafc5b0e5a536b38a1b46f5718c to your computer and use it in GitHub Desktop.
Par
package ch07
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, ExecutionContext, Future}
object ParImpl {
sealed trait Par[A] {
def toFuture(implicit ec: ExecutionContext): Future[A] = {
this match {
case Par.Unit(f) => Future(f())
case Par.Map2(a, b, f) =>
val aFut = a.toFuture
val bFut = b.toFuture
for {
aVal <- aFut
bVal <- bFut
} yield {
f(aVal, bVal)
}
}
}
def getSequentially: A = this match {
case Par.Unit(f) => f()
case Par.Map2(a, b, f) => f(a.getSequentially, b.getSequentially)
}
def get(implicit ec: ExecutionContext): A = Await.result(toFuture, Duration.Inf)
}
object Par {
case class Unit[A](v: () => A) extends Par[A]
case class Map2[A, B, C](parLeft: Par[B], parRight: Par[C], map: (B, C) => A) extends Par[A]
def unit[A](a: => A): Par[A] = Par.Unit(() => a)
def map2[A, B, C](a: Par[B], b: Par[C])(f: (B, C) => A): Par[A] = Par.Map2(a, b, f)
}
}
object Doodle extends App {
import ParImpl._
import scala.concurrent.ExecutionContext.Implicits.global
def sum(ints: IndexedSeq[Int]): Par[Int] =
if (ints.length <= 1)
Par.unit(ints.headOption.getOrElse(0))
else {
val (l, r) = ints.splitAt(ints.length / 2)
Par.map2(sum(l), sum(r))(_ + _)
}
val summedNumbers = sum(IndexedSeq(1, 2, 3, 4)).get
println(summedNumbers)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment