Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
1
SCALAZ 8
A WHOLE NEW GAME
flatMap(Oslo) 2018
By John A. De Goes — @jdegoes
2
Dec 6 2008 May 10 2011 Jul 24 2012
First Commit Scalaz 6.0 Scalaz 7.0
S C A L A Z T I M E L I N E - F R O M 1 T O 8
Scal...
3
SCALAZ 8 CONTRIBUTORS
A F E W O F T H E
Tomas Mikula
@tomas_mikula
Alexander
Konovalov
Jean-Baptiste
Giraudeau
Tim Stein...
4
4 BIG DEALS
TYPE CLASSES
A new encoding of type classes
CATEGORY THEORY
More precise abstractions
OPAQUE TYPES
Power and...
5
TYPE CLASSES
TYPE CLASS HIERARCHY
TYPE CLASS ENCODING
Monoid
Semigroup
TYPE CLASS HEAVEN
6
trait Semigroup[A] {
def append(l: => A, r: => A): A
}
object Semigroup {
def apply[A](implicit S: Semigroup[A]) = S
}
i...
7
implicit val MonoidInt = new Monoid[Int]
{
def zero = 0
def append(l: => Int, r: => Int): Int =
l + r
}
def twice[A: Mon...
8
Traversable Monad
Functor
TYPE CLASSES
TYPE CLASS HIERARCHY
TYPE CLASS ENCODING
TYPE CLASS HELL
9
trait Functor[F[_]] {
...
}
trait Monad[F[_]] extends Functor[F] {
...
}
trait Traversable[F[_]] extends
Functor[F] {
.....
10
implicit val ListTraversable = new Traversable[List] {
...
}
implicit val ListMonad = new Monad[List] {
...
}
def doStu...
11
Traversable Monad
Functor
TYPE CLASSES
TYPE CLASS HIERARCHY
TYPE CLASS ENCODING
TYPE CLASS HEAVEN
12
TYPE CLASSES
TYPE CLASS HIERARCHY
TYPE CLASS ENCODING
TYPE CLASS HEAVEN
sealed abstract class InstanceOfModule {
type I...
13
TYPE CLASSES
TYPE CLASS HIERARCHY
TYPE CLASS ENCODING
TYPE CLASS HEAVEN
trait FunctorClass[F[_]] { … }
trait MonadClass...
14
TYPE CLASSES
TYPE CLASS HIERARCHY
TYPE CLASS ENCODING
TYPE CLASS HEAVEN
implicit val ListTraversable: Traversable[List]...
15
4 BIG DEALS
TYPE CLASSES
A new encoding of type classes
CATEGORY
THEORY
More precise abstractions
OPAQUE TYPES
Power an...
16
CATEGORY THEORY
“FUNCTOR”
FUNCTOR
OPPORTUNITY COST
// OK
trait Functor[F[_]] extends Invariant[F] {
def map[A, B](fa: F...
17
CATEGORY THEORY
“FUNCTOR”
FUNCTOR
OPPORTUNITY COST
18
CATEGORY THEORY
“FUNCTOR”
FUNCTOR
OPPORTUNITY COST
val request: Api[Int] =
GET *>
path("/employees/") *>
contentType("a...
19
CATEGORY THEORY
“FUNCTOR”
FUNCTOR
OPPORTUNITY COST
val charP =
char ^ subset(c => c >= 32 && c != '"' && c != '') |
(te...
20
CATEGORY THEORY
FUNCTOR
ENDOFUNCTOR IN SCALA
OPPORTUNITY GAIN
trait Semicategory[->[_, _]] {
type Obj[A]
def andThen[A:...
21
CATEGORY THEORY
FUNCTOR
ENDOFUNCTOR IN SCALA
OPPORTUNITY GAIN
trait Trivial[A]
type Endofunctor[F[_]] = Functor[F] {
ty...
22
CATEGORY THEORY
FUNCTOR
ENDOFUNCTOR IN SCALA
OPPORTUNITY GAIN
scalaz-http
scalaz-codec
scalaz-parsers
scalaz-rpc
scalaz...
23
4 BIG DEALS
TYPE CLASSES
A new encoding of type classes
CATEGORY THEORY
More precise abstractions
OPAQUE TYPES
Power an...
24
OPAQUE TYPES
INTRODUCTION - MAYBE
FIX - RECURSION SCHEMES
VOID
sealed trait MaybeModule {
type Maybe[A]
object Just {
d...
25
OPAQUE TYPES
INTRODUCTION - MAYBE
FIX - RECURSION SCHEMES
VOID
sealed abstract class InstanceOfModule {
type InstanceOf...
26
OPAQUE TYPES
INTRODUCTION - MAYBE
FIX - RECURSION SCHEMES
VOID
trait FixModule {
type Fix[F[_]]
def fix[F[_]](f: F[data...
27
OPAQUE TYPES
INTRODUCTION - MAYBE
FIX - RECURSION SCHEMES
VOID
trait IListModule {
type IList[A]
def uncons[A](as: ILis...
28
OPAQUE TYPES
INTRODUCTION - MAYBE
FIX - RECURSION SCHEMES
VOID
trait VoidModule {
type Void
def absurd[A](v: Void): A
}...
29
4 BIG DEALS
TYPE CLASSES
A new encoding of type classes
CATEGORY THEORY
More precise abstractions
OPAQUE TYPES
Power an...
30
EFFECTS
// Program #1
val f1 = Future(getProductCategories())
val f2 = Future(getSponsoredProducts())
for {
categories ...
31
EFFECTS
// Program #1
val f1 = Future(getProductCategories())
val f2 = Future(getSponsoredProducts())
for {
categories ...
32
EFFECTS
class Future[+T] {
...
def flatMap[S](f: (T) ⇒ Future[S])(implicit
executor: ExecutionContext): Future[S] = ???...
33
EFFECTS
class Future[+T] {
...
def flatMap[S](f: (T) ⇒ Future[S])(implicit
executor: ExecutionContext): Future[S] = ???...
34
EFFECTS
FUTURE
ERROR HANDLING
CONCURRENCY
IO[E, A]
RESOURCE SAFETY
INTERRUPTION
IOREF[A]
IOQUEUE[A]
EXAMPLE
Future
Fibo...
35
EFFECTS
FUTURE
ERROR HANDLING
CONCURRENCY
IO[E, A]
RESOURCE SAFETY
INTERRUPTION
IOREF[A]
IOQUEUE[A]
EXAMPLE
Future
Fibo...
36
EFFECTS
IO[E, A] FUTURE
ERROR HANDLING
CONCURRENCY
IO[E, A]
RESOURCE SAFETY
INTERRUPTION
IOREF[A]
IOQUEUE[A]
EXAMPLE
An...
37
EFFECTS
FUTURE
ERROR HANDLING
CONCURRENCY
IO[E, A]
RESOURCE SAFETY
INTERRUPTION
IOREF[A]
IOQUEUE[A]
EXAMPLE
IO.point : ...
38
EFFECTS
try {
try {
try throw new Exception("e1")
finally throw new Exception("e2")
} finally throw new Exception("e3")...
39
EFFECTS
FUTURE
ERROR HANDLING
CONCURRENCY
IO[E, A]
RESOURCE SAFETY
INTERRUPTION
IOREF[A]
IOQUEUE[A]
EXAMPLE
Defect: Thr...
40
EFFECTS
FUTURE
ERROR HANDLING
CONCURRENCY
IO[E, A]
RESOURCE SAFETY
INTERRUPTION
IOREF[A]
IOQUEUE[A]
EXAMPLE
val result ...
41
EFFECTS
FUTURE
ERROR HANDLING
CONCURRENCY
IO[E, A]
RESOURCE SAFETY
INTERRUPTION
IOREF[A]
IOQUEUE[A]
EXAMPLE
1. Errors c...
42
EFFECTS
FUTURE
ERROR HANDLING
CONCURRENCY
IO[E, A]
RESOURCE SAFETY
INTERRUPTION
IOREF[A]
IOQUEUE[A]
EXAMPLE
try {
val f...
43
EFFECTS
FUTURE
ERROR HANDLING
CONCURRENCY
IO[E, A]
RESOURCE SAFETY
INTERRUPTION
IOREF[A]
IOQUEUE[A]
EXAMPLE
openFile(f1...
44
EFFECTS
FUTURE
ERROR HANDLING
CONCURRENCY
IO[E, A]
RESOURCE SAFETY
INTERRUPTION
IOREF[A]
IOQUEUE[A]
EXAMPLE
// Fork/joi...
45
EFFECTS
FUTURE
ERROR HANDLING
CONCURRENCY
IO[E, A]
RESOURCE SAFETY
INTERRUPTION
IOREF[A]
IOQUEUE[A]
EXAMPLE
// Parallel...
46
EFFECTS
FUTURE
ERROR HANDLING
CONCURRENCY
IO[E, A]
RESOURCE SAFETY
INTERRUPTION
IOREF[A]
IOQUEUE[A]
EXAMPLE
// Race 2 o...
47
EFFECTS
FUTURE
ERROR HANDLING
CONCURRENCY
IO[E, A]
RESOURCE SAFETY
INTERRUPTION
IOREF[A]
IOQUEUE[A]
EXAMPLE
object cats...
48
EFFECTS
FUTURE
ERROR HANDLING
CONCURRENCY
IO[E, A]
RESOURCE SAFETY
INTERRUPTION
IOREF[A]
IOQUEUE[A]
EXAMPLE
// Computes...
49
EFFECTS
FUTURE
ERROR HANDLING
CONCURRENCY
IO[E, A]
RESOURCE SAFETY
INTERRUPTION
IOREF[A]
IOQUEUE[A]
EXAMPLE
// Purely f...
50
EFFECTS
FUTURE
ERROR HANDLING
CONCURRENCY
IO[E, A]
RESOURCE SAFETY
INTERRUPTION
IOREF[A]
IOQUEUE[A]
EXAMPLE
// Asynchro...
51
EFFECTS
FUTURE
ERROR HANDLING
CONCURRENCY
IO[E, A]
RESOURCE SAFETY
INTERRUPTION
IOREF[A]
IOQUEUE[A]
EXAMPLE
type Actor[...
52
SCALAZ 8 IS
COMING
SOON!
W E W A N T Y O U T O C O N T R I B U T E
THANK YOU!
Thanks to the organizers of flatMap, the
...
Nächste SlideShare
Wird geladen in …5
×

Scalaz 8: A Whole New Game

16.290 Aufrufe

Veröffentlicht am

Scalaz 8 is the latest edition of the popular functional programming library for Scala. In this whirlwind tour, maintainer John A. De Goes discusses some of the hottest features of Scalaz 8, including all of the following:

* A fast, concurrent, and leak-free effect system, which has small, composable, and powerful primitives for building practical, real-world software;
* A non-linear type class hierarchy, which permits a more powerful hierarchy that infers well without devastating ambiguous implicit errors;
* A new encoding for abstractions in category theory that providers higher fidelity and enables new categories of useful software to be developed;
* A Scala 2.12 encoding of opaque types that powers improved performance and better developer UX.

In this tour, you’ll see how the design of Scalaz 8 was inspired by a desire to provide Scala developers with a principled, performant, and pragmatic library that never sacrifices the safety and equational reasoning properties of functional programming. You’ll see live code snippets that show you how solving complex real world problems is simpler, faster, safer, and more reasonable than in previous versions of Scalaz. And hopefully you’ll be inspired at just how far functional programming in Scala has come in the past decade.

Veröffentlicht in: Technologie
  • How to start a wildly profitable 7 figure marketing business and get your first commission check tonight, click here ■■■ https://bit.ly/2kS5a5J
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier
  • @Genevieve Frye I get paid over $426 1 to 2 hours working from home with 2 kids at home. I never thought I'd be able to do it but my best friend earns over $28k a month doing this and she convinced me to try. The potential with this is endless. Heres what I've been doing...... HERE☛ ­­ www.securework99.com ★★★COPY THIS SITE★★★
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier
  • I get paid over $426 1 to 2 hours working from home with 2 kids at home. I never thought I'd be able to do it but my best friend earns over $28k a month doing this and she convinced me to try. The potential with this is endless. Heres what I've been doing...... HERE☛ ­­ www.securework99.com ★★★COPY THIS SITE★★★
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier
  • Doctor's 2-Minute Ritual For Shocking Daily Belly Fat Loss! Watch This Video ▲▲▲ http://scamcb.com/bkfitness3/pdf
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier
  • How to download??
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier

Scalaz 8: A Whole New Game

  1. 1. 1 SCALAZ 8 A WHOLE NEW GAME flatMap(Oslo) 2018 By John A. De Goes — @jdegoes
  2. 2. 2 Dec 6 2008 May 10 2011 Jul 24 2012 First Commit Scalaz 6.0 Scalaz 7.0 S C A L A Z T I M E L I N E - F R O M 1 T O 8 Scalaz is closing in on its 10 year anniversary! SCALAZ 8 WHEN IT’S READY! (SOON) ...
  3. 3. 3 SCALAZ 8 CONTRIBUTORS A F E W O F T H E Tomas Mikula @tomas_mikula Alexander Konovalov Jean-Baptiste Giraudeau Tim Steinbach Aloïs Cochard @alexknvl @jbgi @Tim_Steinbach @aloiscochard Plus Vincent Marquez, Stephen Compall, Edmund Noble, Kenji Yoshida, Emily Pillmore, Jose Cardona, Dale Wijnand, Harrison Houghton, & others. And John!
  4. 4. 4 4 BIG DEALS TYPE CLASSES A new encoding of type classes CATEGORY THEORY More precise abstractions OPAQUE TYPES Power and performance EFFECTS Effects without compromises Let’s explore how Scalaz 8 is changing the game!
  5. 5. 5 TYPE CLASSES TYPE CLASS HIERARCHY TYPE CLASS ENCODING Monoid Semigroup TYPE CLASS HEAVEN
  6. 6. 6 trait Semigroup[A] { def append(l: => A, r: => A): A } object Semigroup { def apply[A](implicit S: Semigroup[A]) = S } implicit class SemigroupSyntax[A](l: A) { def <> (r: => A)(implicit S: Semigroup[A]): A = S.append(l, r) } trait Monoid[A] extends Semigroup[A] { def zero: A } object Monoid { def apply[A](implicit S: Monoid[A]) = S } TYPE CLASSES TYPE CLASS HIERARCHY TYPE CLASS ENCODING TYPE CLASS HEAVEN
  7. 7. 7 implicit val MonoidInt = new Monoid[Int] { def zero = 0 def append(l: => Int, r: => Int): Int = l + r } def twice[A: Monoid](a: A): A = a <> a twice(2) TYPE CLASSES TYPE CLASS HIERARCHY TYPE CLASS ENCODING TYPE CLASS HEAVEN
  8. 8. 8 Traversable Monad Functor TYPE CLASSES TYPE CLASS HIERARCHY TYPE CLASS ENCODING TYPE CLASS HELL
  9. 9. 9 trait Functor[F[_]] { ... } trait Monad[F[_]] extends Functor[F] { ... } trait Traversable[F[_]] extends Functor[F] { ... } TYPE CLASSES TYPE CLASS HIERARCHY TYPE CLASS ENCODING TYPE CLASS HELL
  10. 10. 10 implicit val ListTraversable = new Traversable[List] { ... } implicit val ListMonad = new Monad[List] { ... } def doStuff[F[_]: Traversable: Monad, A, B]( fa: F[A], f: A => F[B]): F[B] = { ... } // ERROR: Ambiguous implicit values for Functor[List] doStuff(1 :: 2 :: 3 :: Nil) TYPE CLASSES TYPE CLASS HIERARCHY TYPE CLASS ENCODING TYPE CLASS HELL
  11. 11. 11 Traversable Monad Functor TYPE CLASSES TYPE CLASS HIERARCHY TYPE CLASS ENCODING TYPE CLASS HEAVEN
  12. 12. 12 TYPE CLASSES TYPE CLASS HIERARCHY TYPE CLASS ENCODING TYPE CLASS HEAVEN sealed abstract class InstanceOfModule { type InstanceOf[T] <: T def instanceOf[T](t: T): InstanceOf[T] } object InstanceOfModule { val impl: InstanceOfModule = new InstanceOfModule { override type InstanceOf[T] = T override def instanceOf[T](t: T) = t } } type InstanceOf[T] = InstanceOfModule.impl.InstanceOf[T] @inline final def instanceOf[T](t: T): InstanceOf[T] = InstanceOfModule.impl.instanceOf(t)
  13. 13. 13 TYPE CLASSES TYPE CLASS HIERARCHY TYPE CLASS ENCODING TYPE CLASS HEAVEN trait FunctorClass[F[_]] { … } trait MonadClass[F[_]] extends FunctorClass[F] { … } trait TraversableClass[F[_]] extends FunctorClass[F] { … } trait BH0 extends BH1 { implicit def monadFunctor[M[_]](implicit M: Monad[M]): Functor[M] = instanceOf(M) } trait BH1 { implicit def traversableFunctor[T[_]]( implicit T: Traversable[T]): Functor[T] = instanceOf(T) } trait BaseTypeclasses { type Functor[F[_]] = InstanceOf[FunctorClass[F]] type Monad[M[_]] = InstanceOf[MonadClass[M]] type Traversable[T[_]] = InstanceOf[TraversableClass[T]] } trait Scalaz extends BH0 with BaseTypeclasses
  14. 14. 14 TYPE CLASSES TYPE CLASS HIERARCHY TYPE CLASS ENCODING TYPE CLASS HEAVEN implicit val ListTraversable: Traversable[List] = instanceOf(new TraversableClass[List] { ... }) implicit val ListMonad: Monad[List] = instanceOf(new MonadClass[List] { ... }) def doStuff[F[_]: Traversable: Monad, A, B]( fa: F[A], f: A => F[B]): F[B] = { ... } // YAY!!!! doStuff(1 :: 2 :: 3 :: Nil)
  15. 15. 15 4 BIG DEALS TYPE CLASSES A new encoding of type classes CATEGORY THEORY More precise abstractions OPAQUE TYPES Power and performance EFFECTS Effects without compromises Let’s explore how Scalaz 8 is changing the game!
  16. 16. 16 CATEGORY THEORY “FUNCTOR” FUNCTOR OPPORTUNITY COST // OK trait Functor[F[_]] extends Invariant[F] { def map[A, B](fa: F[A])(f: A => B): F[B] } // Better trait FunctorClass[F[_]] { def map[A, B](f: A => B): F[A] => F[B] }
  17. 17. 17 CATEGORY THEORY “FUNCTOR” FUNCTOR OPPORTUNITY COST
  18. 18. 18 CATEGORY THEORY “FUNCTOR” FUNCTOR OPPORTUNITY COST val request: Api[Int] = GET *> path("/employees/") *> contentType("application/json") *> queryInt("limit") val response: Api[Json] = contentType("application/json") *> content(JsonCodec) val listEmployees = serviceM(request, response) { limit => loadAllEmployees(limit).toJson } val docs: Markdown = document(listEmployees) val server: IO[Exception, Unit] = compileToServer(listEmployees) val remoteService: Int => IO[Exception, Json] = remotely(listEmployees)("localhost", 80)
  19. 19. 19 CATEGORY THEORY “FUNCTOR” FUNCTOR OPPORTUNITY COST val charP = char ^ subset(c => c >= 32 && c != '"' && c != '') | (text("") *> escapedP) val strP = (text(""") *> charP.many <* text(""")) ^ chars val jStrP = strP ^ str_ ^ fix val digitP = (char ^ subset(c => c >= '0' && c <= '9')).label("digit") val nonZeroP = (char ^ subset(c => c >= '1' && c <= '9')).label("non-zero digit") val numP = (pure(1) | text("-") ^ element(-1)) * (text("0") ^ element("0") | (nonZeroP * digitP.many) ^ cons ^ chars) * (text(".") *> digitP.many1 ^ chars).optional * ((text("e") | text("E")) *> (pure(1) | text("+") ^ element(1) | text("-") ^ element(-1)) * (digitP.many1 ^ chars)).optional
  20. 20. 20 CATEGORY THEORY FUNCTOR ENDOFUNCTOR IN SCALA OPPORTUNITY GAIN trait Semicategory[->[_, _]] { type Obj[A] def andThen[A: Obj, B: Obj, C: Obj] (ab: A -> B, bc: B -> C): A -> C } trait Category[->[_, _]] extends Semicategory[->] { def id[A: Obj]: A -> A } trait Functor[F[_]] { type FromObj[A] type ToObj[A] type FromCat[A, B] type ToCat[A, B] def obj[A : FromObj]: ToObj[F[A]] def map[A : FromObj, B : FromObj](f: FromCat[A, B]): ToCat[F[A], F[B]] }
  21. 21. 21 CATEGORY THEORY FUNCTOR ENDOFUNCTOR IN SCALA OPPORTUNITY GAIN trait Trivial[A] type Endofunctor[F[_]] = Functor[F] { type FromObj[A] = Trivial[A] type ToObj[A] = Trivial[A] type FromCat[A, B] = A => B type ToCat[A, B] = A => B }
  22. 22. 22 CATEGORY THEORY FUNCTOR ENDOFUNCTOR IN SCALA OPPORTUNITY GAIN scalaz-http scalaz-codec scalaz-parsers scalaz-rpc scalaz-analytics ...
  23. 23. 23 4 BIG DEALS TYPE CLASSES A new encoding of type classes CATEGORY THEORY More precise abstractions OPAQUE TYPES Power and performance EFFECTS Effects without compromises Let’s explore how Scalaz 8 is changing the game!
  24. 24. 24 OPAQUE TYPES INTRODUCTION - MAYBE FIX - RECURSION SCHEMES VOID sealed trait MaybeModule { type Maybe[A] object Just { def unapply[A](ma: Maybe[A]): Option[A] = toOption(ma) } object Empty { def unapply[A](ma: Maybe[A]): Boolean = toOption(ma).isEmpty } def empty[A]: Maybe[A] def just[A](a: A): Maybe[A] def maybe[A, B](n: B)(f: A => B): Maybe[A] => B def fromOption[A](oa: Option[A]): Maybe[A] def toOption[A](ma: Maybe[A]): Option[A] } private[scalaz] object MaybeImpl extends MaybeModule { ... } final val Maybe: MaybeModule = MaybeImpl type Maybe[A] = Maybe.Maybe[A] TYPE CLASS HIERARCHY LIST - VIA FIX
  25. 25. 25 OPAQUE TYPES INTRODUCTION - MAYBE FIX - RECURSION SCHEMES VOID sealed abstract class InstanceOfModule { type InstanceOf[T] <: T def instanceOf[T](t: T): InstanceOf[T] } object InstanceOfModule { val impl: InstanceOfModule = new InstanceOfModule { override type InstanceOf[T] = T override def instanceOf[T](t: T) = t } } type InstanceOf[T] = InstanceOfModule.impl.InstanceOf[T] @inline final def instanceOf[T](t: T): InstanceOf[T] = InstanceOfModule.impl.instanceOf(t) TYPE CLASS HIERARCHY LIST - VIA FIX
  26. 26. 26 OPAQUE TYPES INTRODUCTION - MAYBE FIX - RECURSION SCHEMES VOID trait FixModule { type Fix[F[_]] def fix[F[_]](f: F[data.Fix[F]]): Fix[F] def unfix[F[_]](f: Fix[F]): F[data.Fix[F]] } private[data] object FixImpl extends FixModule { type Fix[F[_]] = F[data.Fix[F]] def fix[F[_]](f: F[data.Fix[F]]): Fix[F] = f def unfix[F[_]](f: Fix[F]): F[data.Fix[F]] = f } TYPE CLASS HIERARCHY LIST - VIA FIX
  27. 27. 27 OPAQUE TYPES INTRODUCTION - MAYBE FIX - RECURSION SCHEMES VOID trait IListModule { type IList[A] def uncons[A](as: IList[A]): Maybe2[A, IList[A]] } private[data] object IListImpl extends IListModule { type IList[A] = Fix[Maybe2[A, ?]] def uncons[A](as: IList[A]): Maybe2[A, IList[A]] = Fix.unfix[Maybe2[A, ?]](as) } TYPE CLASS HIERARCHY LIST - VIA FIX
  28. 28. 28 OPAQUE TYPES INTRODUCTION - MAYBE FIX - RECURSION SCHEMES VOID trait VoidModule { type Void def absurd[A](v: Void): A } @silent private[data] object VoidImpl extends VoidModule { type Void = Nothing def absurd[A](v: Void): A = v } TYPE CLASS HIERARCHY LIST - VIA FIX
  29. 29. 29 4 BIG DEALS TYPE CLASSES A new encoding of type classes CATEGORY THEORY More precise abstractions OPAQUE TYPES Power and performance EFFECTS Effects without compromises Let’s explore how Scalaz 8 is changing the game!
  30. 30. 30 EFFECTS // Program #1 val f1 = Future(getProductCategories()) val f2 = Future(getSponsoredProducts()) for { categories <- f1 sponsored <- f2 response <- buildResults(categories, sponsored) } yield response // Program #2 for { categories <- Future(getProductCategories()) sponsored <- Future(getSponsoredProducts()) response <- buildResults(categories, sponsored) } yield response FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE ≠
  31. 31. 31 EFFECTS // Program #1 val f1 = Future(getProductCategories()) val f2 = Future(getSponsoredProducts()) for { categories <- f1 sponsored <- f2 response <- buildResults(categories, sponsored) } yield response // Program #2 for { categories <- Future(getProductCategories()) sponsored <- Future(getSponsoredProducts()) response <- buildResults(categories, sponsored) } yield response FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE ≠
  32. 32. 32 EFFECTS class Future[+T] { ... def flatMap[S](f: (T) ⇒ Future[S])(implicit executor: ExecutionContext): Future[S] = ??? ... } FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLEAccidental pooling
  33. 33. 33 EFFECTS class Future[+T] { ... def flatMap[S](f: (T) ⇒ Future[S])(implicit executor: ExecutionContext): Future[S] = ??? ... } FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLEAccidental pooling
  34. 34. 34 EFFECTS FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE Future Fibonacci Benchmark http://github.com/scalaz/scalaz 115x FASTER!
  35. 35. 35 EFFECTS FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE Future Fibonacci Benchmark http://github.com/scalaz/scalaz 115x FASTER!
  36. 36. 36 EFFECTS IO[E, A] FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE An immutable value that describes an effectful (I/O) program that may run forever, terminate due to defect... ...“fail” with a value of type E... or synchronously / asynchronously compute a value of type A.
  37. 37. 37 EFFECTS FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE IO.point : (=> A) => IO[E, A] Lifts a pure A value into an IO data structure. IO.fail : E => IO[E, A] Creates a value representing failure with an E. IO.terminate : Throwable => IO[E, A] Terminates the currently executing fiber with a non-recoverable error. IO.sync : (=> A) => IO[E, A] Captures a synchronous effect inside a pure data structure. IO.async : <asynchronous> Captures an asynchronous effect inside a pure data structure. io.attempt[E2]: IO[E2, E / A] Creates an error-free value by surfacing any error into E / A. io.map(f: A => B): IO[E, B] Maps one value into another by applying the function on A. io.flatMap(f: A => IO[E, B]): IO[E, B] Sequences one value into another whose construction depends on the first value.
  38. 38. 38 EFFECTS try { try { try throw new Exception("e1") finally throw new Exception("e2") } finally throw new Exception("e3") } catch { // WHICH ONE??? case e : Exception => println(e.toString()) } FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE Two exceptions are swallowed!!!
  39. 39. 39 EFFECTS FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE Defect: Throwable Non-Recoverable Error Error State: E Recoverable Error Recover with attempt : IO[E, A] => IO[Void, E / A] Unhandled E Pass to fiber supervisor: Throwable => IO[Void, Unit] Terminate fiber (“Let it Crash”) Interruption
  40. 40. 40 EFFECTS FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE val result : IO[Void, String / A] = IO.fail(“e1”).ensuring( IO.terminate(new Error(“e2”)).ensuring( IO.terminate(new Error(“e3)).attempt result.flatMap(putStrLn(_)) // ???
  41. 41. 41 EFFECTS FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE 1. Errors can be handled completely to yield infallible computations IO[Void, A] 2. There is no way to lose any error, whether recoverable or non-recoverable 3. Unlike other approaches, all functor laws are completely satisfied 4. There is no magical auto-catching or tangling of the E error channel to Throwable 5. There are no inconsistencies in the error model and it seamlessly integrates with typed error staes, interruptions, resource safety
  42. 42. 42 EFFECTS FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE try { val file1 = openFile(“file.1”) try { val file2 = openFile(“file.2”) joinFiles(file1, file2) } finally file2.close() } finally file1.close()
  43. 43. 43 EFFECTS FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE openFile(f1).bracket(_.close()) { file1 => openFile(f2).bracket(_.close()) { file2 => joinFile(file1, file2) } } Acquire Release Use
  44. 44. 44 EFFECTS FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE // Fork/join: def concurrentFib(n: Int): IO[Void, BigInt] = if (n <= 1) IO.point[Void, BigInt](n) else for { f1 <- concurrentFib(n - 1).fork f2 <- concurrentFib(n - 2).fork v1 <- f1.join v2 <- f2.join } yield v1 + v2
  45. 45. 45 EFFECTS FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE // Parallelism: val ioAB : IO[E, (A, B)] = ioA.par(ioB)
  46. 46. 46 EFFECTS FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE // Race 2 or more actions: val rez = getUrl(“primary”) race ( getUrl(“backup”))
  47. 47. 47 EFFECTS FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE object cats { def fib(n: Int): IO[BigInt] = if (n <= 1) IO(n) else fib(n - 1).flatMap { a => fib(n - 2).flatMap(b => IO(a + b)) } } object scalaz { def fib(n: Int): IO[Void, BigInt] = if (n <= 1) IO.point[Void, BigInt](n) else fib(n - 1).flatMap { a => fib(n - 2).flatMap(b => IO.point(a + b)) } } // Never finishes!!! cats.fib(Int.MaxValue).start(_.cancel) // Interrupts immediately with cleanup: scalaz.fib(Int.MaxValue).fork(_.interrupt(???))
  48. 48. 48 EFFECTS FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE // Computes forever!!! cats.fib(Int.MaxValue). race(cats.fib(10)) // Computes quickly by // interrupting loser: scalaz.fib(Int.MaxValue). race(scalaz.fib(10))
  49. 49. 49 EFFECTS FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE // Purely functional, concurrent `var` for { ref <- IORef(2) v <- ref.modify(_ + 3) _ <- putStrLn("Value = " + v.debug) } yield ()
  50. 50. 50 EFFECTS FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE // Asynchronous, non-blocking queue: for { queue <- IOQueue.make[Int] fiber <- queue.take.fork _ <- queue.offer(3) v <- fiber.join } yield v
  51. 51. 51 EFFECTS FUTURE ERROR HANDLING CONCURRENCY IO[E, A] RESOURCE SAFETY INTERRUPTION IOREF[A] IOQUEUE[A] EXAMPLE type Actor[E, I, O] = I => IO[E, O] implicit class ActorSyntax[E, I, O](actor: Actor[E, I, O]) { def ! (i: I): IO[E, O] = actor(i) } val makeActor: IO[Void, Actor[Void, Int, Int]] = for { counter <- IORef(0) queue <- IOQueue.make[(Int, Promise[Void, Int])] worker <- queue.take.flatMap(t => counter.modify(_ + t._1).flatMap(t._2.complete)).forever.fork actor = (n: Int) => for { promise <- Promise.make[Void, Int] _ <- queue.offer((n, promise)) value <- promise.get } yield value } yield actor ... for { actor <- makeActor v <- actor ! 20 } yield v
  52. 52. 52 SCALAZ 8 IS COMING SOON! W E W A N T Y O U T O C O N T R I B U T E THANK YOU! Thanks to the organizers of flatMap, the sponsors, & attendees. Follow me @jdegoes Join Scalaz at gitter.im/scalaz/scalaz T H E E N D

×