Scalaz 8: A Whole New Game

John De Goes
John De GoesCTO at SlamData
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
Scalaz is closing in on its 10 year anniversary!
SCALAZ 8
WHEN IT’S READY!
(SOON)
...
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 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
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
}
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
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
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] {
...
}
TYPE CLASSES
TYPE CLASS HIERARCHY
TYPE CLASS ENCODING
TYPE CLASS HELL
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
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 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
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
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
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
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
CATEGORY THEORY
“FUNCTOR”
FUNCTOR
OPPORTUNITY COST
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
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
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
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
CATEGORY THEORY
FUNCTOR
ENDOFUNCTOR IN SCALA
OPPORTUNITY GAIN
scalaz-http
scalaz-codec
scalaz-parsers
scalaz-rpc
scalaz-analytics
...
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
1 of 52

Recommended

Refactoring Functional Type Classes by
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type ClassesJohn De Goes
6.9K views74 slides
The Death of Final Tagless by
The Death of Final TaglessThe Death of Final Tagless
The Death of Final TaglessJohn De Goes
4.6K views118 slides
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics by
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsJohn De Goes
7.2K views32 slides
Functor, Apply, Applicative And Monad by
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadOliver Daff
2.5K views126 slides
One Monad to Rule Them All by
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them AllJohn De Goes
4.6K views79 slides
First-Class Patterns by
First-Class PatternsFirst-Class Patterns
First-Class PatternsJohn De Goes
3.3K views30 slides

More Related Content

What's hot

Post-Free: Life After Free Monads by
Post-Free: Life After Free MonadsPost-Free: Life After Free Monads
Post-Free: Life After Free MonadsJohn De Goes
3.8K views72 slides
Monad Transformers In The Wild by
Monad Transformers In The WildMonad Transformers In The Wild
Monad Transformers In The WildStackMob Inc
3.9K views81 slides
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming... by
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...John De Goes
1.6K views107 slides
Atomically { Delete Your Actors } by
Atomically { Delete Your Actors }Atomically { Delete Your Actors }
Atomically { Delete Your Actors }John De Goes
2.1K views116 slides
Hammurabi by
HammurabiHammurabi
HammurabiMario Fusco
3.3K views25 slides
The Next Great Functional Programming Language by
The Next Great Functional Programming LanguageThe Next Great Functional Programming Language
The Next Great Functional Programming LanguageJohn De Goes
4.2K views48 slides

What's hot(20)

Post-Free: Life After Free Monads by John De Goes
Post-Free: Life After Free MonadsPost-Free: Life After Free Monads
Post-Free: Life After Free Monads
John De Goes3.8K views
Monad Transformers In The Wild by StackMob Inc
Monad Transformers In The WildMonad Transformers In The Wild
Monad Transformers In The Wild
StackMob Inc3.9K views
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming... by John De Goes
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
John De Goes1.6K views
Atomically { Delete Your Actors } by John De Goes
Atomically { Delete Your Actors }Atomically { Delete Your Actors }
Atomically { Delete Your Actors }
John De Goes2.1K views
The Next Great Functional Programming Language by John De Goes
The Next Great Functional Programming LanguageThe Next Great Functional Programming Language
The Next Great Functional Programming Language
John De Goes4.2K views
Fp in scala part 1 by Hang Zhao
Fp in scala part 1Fp in scala part 1
Fp in scala part 1
Hang Zhao961 views
Introduction to Monads in Scala (1) by stasimus
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)
stasimus10.2K views
Learning Functional Programming Without Growing a Neckbeard by Kelsey Gilmore-Innis
Learning Functional Programming Without Growing a NeckbeardLearning Functional Programming Without Growing a Neckbeard
Learning Functional Programming Without Growing a Neckbeard
Kelsey Gilmore-Innis25.3K views
Intro to Functional Programming in Scala by Shai Yallin
Intro to Functional Programming in ScalaIntro to Functional Programming in Scala
Intro to Functional Programming in Scala
Shai Yallin2K views
Halogen: Past, Present, and Future by John De Goes
Halogen: Past, Present, and FutureHalogen: Past, Present, and Future
Halogen: Past, Present, and Future
John De Goes2.9K views
Joy of scala by Maxim Novak
Joy of scalaJoy of scala
Joy of scala
Maxim Novak13.3K views
The Design of the Scalaz 8 Effect System by John De Goes
The Design of the Scalaz 8 Effect SystemThe Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect System
John De Goes5.5K views
Fp in scala with adts part 2 by Hang Zhao
Fp in scala with adts part 2Fp in scala with adts part 2
Fp in scala with adts part 2
Hang Zhao1K views
Demystifying functional programming with Scala by Denis
Demystifying functional programming with ScalaDemystifying functional programming with Scala
Demystifying functional programming with Scala
Denis 535 views
Scala - where objects and functions meet by Mario Fusco
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
Mario Fusco1.8K views
Monoids, Monoids, Monoids - ScalaLove 2020 by Luka Jacobowitz
Monoids, Monoids, Monoids - ScalaLove 2020Monoids, Monoids, Monoids - ScalaLove 2020
Monoids, Monoids, Monoids - ScalaLove 2020
Luka Jacobowitz739 views
Scala Back to Basics: Type Classes by Tomer Gabel
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
Tomer Gabel3.7K views
Advanced Tagless Final - Saying Farewell to Free by Luka Jacobowitz
Advanced Tagless Final - Saying Farewell to FreeAdvanced Tagless Final - Saying Farewell to Free
Advanced Tagless Final - Saying Farewell to Free
Luka Jacobowitz2K views

Similar to Scalaz 8: A Whole New Game

Scala Paradigms by
Scala ParadigmsScala Paradigms
Scala ParadigmsTom Flaherty
1.7K views35 slides
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e... by
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...PROIDEA
409 views410 slides
Scala collections api expressivity and brevity upgrade from java by
Scala collections api  expressivity and brevity upgrade from javaScala collections api  expressivity and brevity upgrade from java
Scala collections api expressivity and brevity upgrade from javaIndicThreads
677 views9 slides
An Introduction to Part of C++ STL by
An Introduction to Part of C++ STLAn Introduction to Part of C++ STL
An Introduction to Part of C++ STL乐群 陈
2K views58 slides
Scala基礎勉強会: Featherweight Scalaの紹介および型付け規則の決定可能性について by
Scala基礎勉強会: Featherweight Scalaの紹介および型付け規則の決定可能性についてScala基礎勉強会: Featherweight Scalaの紹介および型付け規則の決定可能性について
Scala基礎勉強会: Featherweight Scalaの紹介および型付け規則の決定可能性についてHiroki Mizuno
1.7K views35 slides
Abstracting Vector Architectures in Library Generators: Case Study Convolutio... by
Abstracting Vector Architectures in Library Generators: Case Study Convolutio...Abstracting Vector Architectures in Library Generators: Case Study Convolutio...
Abstracting Vector Architectures in Library Generators: Case Study Convolutio...ETH Zurich
2.4K views26 slides

Similar to Scalaz 8: A Whole New Game(20)

JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e... by PROIDEA
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
PROIDEA409 views
Scala collections api expressivity and brevity upgrade from java by IndicThreads
Scala collections api  expressivity and brevity upgrade from javaScala collections api  expressivity and brevity upgrade from java
Scala collections api expressivity and brevity upgrade from java
IndicThreads677 views
An Introduction to Part of C++ STL by 乐群 陈
An Introduction to Part of C++ STLAn Introduction to Part of C++ STL
An Introduction to Part of C++ STL
乐群 陈2K views
Scala基礎勉強会: Featherweight Scalaの紹介および型付け規則の決定可能性について by Hiroki Mizuno
Scala基礎勉強会: Featherweight Scalaの紹介および型付け規則の決定可能性についてScala基礎勉強会: Featherweight Scalaの紹介および型付け規則の決定可能性について
Scala基礎勉強会: Featherweight Scalaの紹介および型付け規則の決定可能性について
Hiroki Mizuno1.7K views
Abstracting Vector Architectures in Library Generators: Case Study Convolutio... by ETH Zurich
Abstracting Vector Architectures in Library Generators: Case Study Convolutio...Abstracting Vector Architectures in Library Generators: Case Study Convolutio...
Abstracting Vector Architectures in Library Generators: Case Study Convolutio...
ETH Zurich2.4K views
Postgresql 9.3 overview by Aveic
Postgresql 9.3 overviewPostgresql 9.3 overview
Postgresql 9.3 overview
Aveic2K views
Beginning Scala Svcc 2009 by David Pollak
Beginning Scala Svcc 2009Beginning Scala Svcc 2009
Beginning Scala Svcc 2009
David Pollak855 views
The Ring programming language version 1.10 book - Part 45 of 212 by Mahmoud Samir Fayed
The Ring programming language version 1.10 book - Part 45 of 212The Ring programming language version 1.10 book - Part 45 of 212
The Ring programming language version 1.10 book - Part 45 of 212
Introduction to scala by Michel Perez
Introduction to scalaIntroduction to scala
Introduction to scala
Michel Perez192 views
Functional programming with_scala by Raymond Tay
Functional programming with_scalaFunctional programming with_scala
Functional programming with_scala
Raymond Tay2.1K views
Peeking inside the engine of ZIO SQL.pdf by JaroslavRegec1
Peeking inside the engine of ZIO SQL.pdfPeeking inside the engine of ZIO SQL.pdf
Peeking inside the engine of ZIO SQL.pdf
JaroslavRegec1153 views
A Prelude of Purity: Scaling Back ZIO by Jorge Vásquez
A Prelude of Purity: Scaling Back ZIOA Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIO
Jorge Vásquez431 views
Automatic Type Class Derivation with Shapeless by jcazevedo
Automatic Type Class Derivation with ShapelessAutomatic Type Class Derivation with Shapeless
Automatic Type Class Derivation with Shapeless
jcazevedo444 views
An introduction to functional programming with Swift by Fatih Nayebi, Ph.D.
An introduction to functional programming with SwiftAn introduction to functional programming with Swift
An introduction to functional programming with Swift
STRING LIST TUPLE DICTIONARY FILE.pdf by omprakashmeena48
STRING LIST TUPLE DICTIONARY FILE.pdfSTRING LIST TUPLE DICTIONARY FILE.pdf
STRING LIST TUPLE DICTIONARY FILE.pdf
omprakashmeena48695 views
Type Classes in Scala and Haskell by Hermann Hueck
Type Classes in Scala and HaskellType Classes in Scala and Haskell
Type Classes in Scala and Haskell
Hermann Hueck1.4K views
All About ... Functions by Michal Bigos
All About ... FunctionsAll About ... Functions
All About ... Functions
Michal Bigos792 views

More from John De Goes

Error Management: Future vs ZIO by
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIOJohn De Goes
13.6K views73 slides
Scalaz Stream: Rebirth by
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: RebirthJohn De Goes
2.5K views119 slides
Scalaz Stream: Rebirth by
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: RebirthJohn De Goes
2K views119 slides
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming by
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional ProgrammingZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional ProgrammingJohn De Goes
4.1K views92 slides
ZIO Queue by
ZIO QueueZIO Queue
ZIO QueueJohn De Goes
3.1K views60 slides
Scalaz 8 vs Akka Actors by
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsJohn De Goes
7K views31 slides

More from John De Goes(17)

Error Management: Future vs ZIO by John De Goes
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIO
John De Goes13.6K views
Scalaz Stream: Rebirth by John De Goes
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
John De Goes2.5K views
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming by John De Goes
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional ProgrammingZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
John De Goes4.1K views
Scalaz 8 vs Akka Actors by John De Goes
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka Actors
John De Goes7K views
Orthogonal Functional Architecture by John De Goes
Orthogonal Functional ArchitectureOrthogonal Functional Architecture
Orthogonal Functional Architecture
John De Goes4.9K views
Streams for (Co)Free! by John De Goes
Streams for (Co)Free!Streams for (Co)Free!
Streams for (Co)Free!
John De Goes2.1K views
All Aboard The Scala-to-PureScript Express! by John De Goes
All Aboard The Scala-to-PureScript Express!All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!
John De Goes1.8K views
Getting Started with PureScript by John De Goes
Getting Started with PureScriptGetting Started with PureScript
Getting Started with PureScript
John De Goes2.3K views
SlamData - How MongoDB Is Powering a Revolution in Visual Analytics by John De Goes
SlamData - How MongoDB Is Powering a Revolution in Visual AnalyticsSlamData - How MongoDB Is Powering a Revolution in Visual Analytics
SlamData - How MongoDB Is Powering a Revolution in Visual Analytics
John De Goes3.7K views
The Dark Side of NoSQL by John De Goes
The Dark Side of NoSQLThe Dark Side of NoSQL
The Dark Side of NoSQL
John De Goes1.4K views
Quirrel & R for Dummies by John De Goes
Quirrel & R for DummiesQuirrel & R for Dummies
Quirrel & R for Dummies
John De Goes1.5K views
In-Database Predictive Analytics by John De Goes
In-Database Predictive AnalyticsIn-Database Predictive Analytics
In-Database Predictive Analytics
John De Goes4.3K views
Analytics Maturity Model by John De Goes
Analytics Maturity ModelAnalytics Maturity Model
Analytics Maturity Model
John De Goes8.1K views
Rise of the scientific database by John De Goes
Rise of the scientific databaseRise of the scientific database
Rise of the scientific database
John De Goes2.1K views

Recently uploaded

20231123_Camunda Meetup Vienna.pdf by
20231123_Camunda Meetup Vienna.pdf20231123_Camunda Meetup Vienna.pdf
20231123_Camunda Meetup Vienna.pdfPhactum Softwareentwicklung GmbH
41 views73 slides
6g - REPORT.pdf by
6g - REPORT.pdf6g - REPORT.pdf
6g - REPORT.pdfLiveplex
10 views23 slides
MVP and prioritization.pdf by
MVP and prioritization.pdfMVP and prioritization.pdf
MVP and prioritization.pdfrahuldharwal141
31 views8 slides
The Research Portal of Catalonia: Growing more (information) & more (services) by
The Research Portal of Catalonia: Growing more (information) & more (services)The Research Portal of Catalonia: Growing more (information) & more (services)
The Research Portal of Catalonia: Growing more (information) & more (services)CSUC - Consorci de Serveis Universitaris de Catalunya
80 views25 slides
PRODUCT PRESENTATION.pptx by
PRODUCT PRESENTATION.pptxPRODUCT PRESENTATION.pptx
PRODUCT PRESENTATION.pptxangelicacueva6
15 views1 slide
Evolving the Network Automation Journey from Python to Platforms by
Evolving the Network Automation Journey from Python to PlatformsEvolving the Network Automation Journey from Python to Platforms
Evolving the Network Automation Journey from Python to PlatformsNetwork Automation Forum
13 views21 slides

Recently uploaded(20)

6g - REPORT.pdf by Liveplex
6g - REPORT.pdf6g - REPORT.pdf
6g - REPORT.pdf
Liveplex10 views
Business Analyst Series 2023 - Week 3 Session 5 by DianaGray10
Business Analyst Series 2023 -  Week 3 Session 5Business Analyst Series 2023 -  Week 3 Session 5
Business Analyst Series 2023 - Week 3 Session 5
DianaGray10300 views
Case Study Copenhagen Energy and Business Central.pdf by Aitana
Case Study Copenhagen Energy and Business Central.pdfCase Study Copenhagen Energy and Business Central.pdf
Case Study Copenhagen Energy and Business Central.pdf
Aitana16 views
Unit 1_Lecture 2_Physical Design of IoT.pdf by StephenTec
Unit 1_Lecture 2_Physical Design of IoT.pdfUnit 1_Lecture 2_Physical Design of IoT.pdf
Unit 1_Lecture 2_Physical Design of IoT.pdf
StephenTec12 views
SAP Automation Using Bar Code and FIORI.pdf by Virendra Rai, PMP
SAP Automation Using Bar Code and FIORI.pdfSAP Automation Using Bar Code and FIORI.pdf
SAP Automation Using Bar Code and FIORI.pdf
HTTP headers that make your website go faster - devs.gent November 2023 by Thijs Feryn
HTTP headers that make your website go faster - devs.gent November 2023HTTP headers that make your website go faster - devs.gent November 2023
HTTP headers that make your website go faster - devs.gent November 2023
Thijs Feryn22 views
Serverless computing with Google Cloud (2023-24) by wesley chun
Serverless computing with Google Cloud (2023-24)Serverless computing with Google Cloud (2023-24)
Serverless computing with Google Cloud (2023-24)
wesley chun11 views
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院 by IttrainingIttraining
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院
iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas... by Bernd Ruecker
iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas...iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas...
iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas...
Bernd Ruecker40 views
TrustArc Webinar - Managing Online Tracking Technology Vendors_ A Checklist f... by TrustArc
TrustArc Webinar - Managing Online Tracking Technology Vendors_ A Checklist f...TrustArc Webinar - Managing Online Tracking Technology Vendors_ A Checklist f...
TrustArc Webinar - Managing Online Tracking Technology Vendors_ A Checklist f...
TrustArc11 views
PharoJS - Zürich Smalltalk Group Meetup November 2023 by Noury Bouraqadi
PharoJS - Zürich Smalltalk Group Meetup November 2023PharoJS - Zürich Smalltalk Group Meetup November 2023
PharoJS - Zürich Smalltalk Group Meetup November 2023
Noury Bouraqadi132 views

Scalaz 8: A Whole New Game

  • 1. 1 SCALAZ 8 A WHOLE NEW GAME flatMap(Oslo) 2018 By John A. De Goes — @jdegoes
  • 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 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 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 TYPE CLASSES TYPE CLASS HIERARCHY TYPE CLASS ENCODING Monoid Semigroup TYPE CLASS HEAVEN
  • 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 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 Traversable Monad Functor TYPE CLASSES TYPE CLASS HIERARCHY TYPE CLASS ENCODING TYPE CLASS HELL
  • 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 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 Traversable Monad Functor TYPE CLASSES TYPE CLASS HIERARCHY TYPE CLASS ENCODING TYPE CLASS HEAVEN
  • 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 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 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 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 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] }
  • 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 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 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 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 CATEGORY THEORY FUNCTOR ENDOFUNCTOR IN SCALA OPPORTUNITY GAIN scalaz-http scalaz-codec scalaz-parsers scalaz-rpc scalaz-analytics ...
  • 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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