SlideShare une entreprise Scribd logo
1  sur  74
Télécharger pour lire hors ligne
SF Scala Meetup - July 30, 2020
John A. De Goes — @jdegoes
Adam Fraser — @adamfraser
Refactoring Functional
Type Classes
WHY YOU’RE
HERE
“Let me tell you why you’re here. You’re here
because you know something. What you know
you can’t explain, but you feel it. You’ve felt it
your entire life, that there’s something wrong
with the world. You don’t know what it is, but
it’s there, like a splinter in your mind, driving
you mad. It is this feeling that has brought you
to me. Do you know what I’m talking about?”
— Morpheus, The Matrix
TABLE OF
CONTENTS
01
THE LEGEND OF FUNCTOR
The supreme reign of the Haskell functor hierarchy
02
TROUBLE IN FUNCTOR TOWN
Drawbacks of the classic functor hierarchy
03
EASY ALGEBRA
Unlike category theory, you already know algebra
04
TOUR OF ZIO PRELUDE
An algebraic, modular, & Scala-first basis for type classes
THE LEGEND
OF FUNCTOR
Functor
THE LEGEND
OF FUNCTOR
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
Functor -> Apply
THE LEGEND
OF FUNCTOR
trait Apply[F[_]] extends Functor[F] {
def map[A, B](fa: F[A])(f: A => B): F[B]
def ap[A, B](ff: F[A => B])(f: F[A]): F[B]
}
Functor -> Apply -> Applicative
THE LEGEND
OF FUNCTOR
trait Applicative[F[_]] extends Apply[F] {
def map[A, B](fa: F[A])(f: A => B): F[B]
def ap[A, B](ff: F[A => B])(f: F[A]): F[B]
def pure[A](a: A): F[A]
}
Functor -> Apply -> Applicative -> Monad
THE LEGEND
OF FUNCTOR
trait Monad[F[_]] extends Applicative[F] {
def map[A, B](fa: F[A])(f: A => B): F[B]
def ap[A, B](ff: F[A => B])(f: F[A]): F[B]
def pure[A](a: A): F[A]
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
}
*Bind is skipped.
THE LEGEND OF
FUNCTOR
The Ubiquity of Functor in
Functional Programming
● Haskell
● Scala
○ Scalaz
○ Cats
● Kotlin
● Java
● F#
● Idris
● And many others!
9
Books Have Been Written About It
THE LEGEND
OF FUNCTOR
TROUBLE IN
FUNCTOR TOWN
The Curse of Haskellisms
TROUBLE IN
FUNCTOR TOWN
def ap[A, B](
ff: F[A => B], fa: F[A]): F[B]
f :: Int -> Int -> Int -> Int
f <$> arg1 <*> arg2 <*> arg3
Set Is Not A “Functor”?
TROUBLE IN
FUNCTOR TOWN
set.map(f).map(g)
set.map(f andThen g)
f g f.andThen(g)
A B C A C
The Functor Hierarchy Is A Lie!
TROUBLE IN
FUNCTOR TOWN
Functor in FP
Functor in Math
ZIO Config
TROUBLE IN
FUNCTOR TOWN
(string(“server”) |@|
int(“port”))(
Config.apply(_),
Config.unapply(_))
ZIO Codec
TROUBLE IN
FUNCTOR TOWN
lazy val js: Codec[Val] =
((spacing, ()) ~>
(obj | arr | str | `true` |
`false` | `null` | num)
<~ ((), spacing))
Introspectable Monads
TROUBLE IN
FUNCTOR TOWN for {
bool <- boolParser
value <- if (bool) parserA
else parserB
} yield value
Constrained DSLs
TROUBLE IN
FUNCTOR TOWN
def map[A, B](fa: F[A])(f: A => B): F[B]
val fa: F[A] = …
val f : A => B = …
fa.map(a => f(a))
Type B is unconstrainable!
Invariance Pain
TROUBLE IN
FUNCTOR TOWN
val functorDog: F[Dog] = …
val functorAnimal: F[Animal] =
functorDog
ERROR!!!
Invariance Pain
TROUBLE IN
FUNCTOR TOWN
val functorDog: F[Dog] = …
val functorAnimal: F[Animal] =
functorDog.widen[Animal]
Stack-Exploding Strictness
TROUBLE IN
FUNCTOR TOWN
def forever[A](fa: F[A]): F[A] =
fa *> forever(fa)
Lawless Type Classes & Operations
TROUBLE IN
FUNCTOR TOWN
Defer
Foldable
Monad#tailRecM
Parallel
NonEmptyParallel
UnorderedFoldable
Type Class Proliferation
TROUBLE IN
FUNCTOR TOWN
Align
Alternative
Always
Applicative
ApplicativeError
Apply
Bifoldable
Bifunctor
Bimonad
Bitraverse
CoflatMap
CommutativeApplicative
CommutativeApply
CommutativeFlatMap
CommutativeMonad
Comonad
Contravariant
ContravariantMonoidal
ContravariantSemigroupal
Defer
Distributive
Eval
EvalGroup
EvalMonoid
EvalSemigroup
FlatMap
Foldable
Functor
FunctorFilter
Inject
InjectK
Invariant
InvariantMonoidal
InvariantSemigroupal
Later
Monad
MonadError
MonoidK
NonEmptyParallelNonEmptyR
educible
NonEmptyTraverse
NotNull
Now
Parallel
Reducible
Representable
SemigroupK
Semigroupal
Show
StackSafeMonad
Traverse
TraverseFilter
UnorderedFoldable
UnorderedTraverse
Type Class Proliferation
TROUBLE IN
FUNCTOR TOWN
Align
Alternative
Always
Applicative
ApplicativeError
Apply
Bifoldable
Bifunctor
Bimonad
Bitraverse
CoflatMap
CommutativeApplicative
CommutativeApply
CommutativeFlatMap
CommutativeMonad
Comonad
Contravariant
ContravariantMonoidal
ContravariantSemigroupal
Defer
Distributive
Eval
EvalGroup
EvalMonoid
EvalSemigroup
FlatMap
Foldable
Functor
FunctorFilter
Inject
InjectK
Invariant
InvariantMonoidal
InvariantSemigroupal
Later
Monad
MonadError
MonoidK
NonEmptyParallelNonEmptyR
educible
NonEmptyTraverse
NotNull
Now
Parallel
Reducible
Representable
SemigroupK
Semigroupal
Show
StackSafeMonad
Traverse
TraverseFilter
UnorderedFoldable
UnorderedTraverse
*meme from dev.to
Maddening Monad Transformers
TROUBLE IN
FUNCTOR TOWN
type MyApp[E, W, S, R, A] =
OptionT[
EitherT[
WriterT[
StateT[
Kleisli[Task, R, *],
S, *],
W, *],
E, *],
*]
TROUBLE IN
FUNCTOR TOWN
Is There Another Way?
EASY ALGEBRA
EASY ALGEBRA
// Set of elements
type Int
// Operations on those elements
def plus(x: Int, y: Int): Int
// Laws about those operations
x + (y + z) == (x + y) + z
x + y == y + x
You Already Know This
EASY ALGEBRA
Associativity
// Set of elements
type A
// Operations on those elements
def combine(l: A, r: A): A
// Laws about those operations
a1 <> (a2 <> a3) == (a1 <> a2) <> a3
EASY ALGEBRA
Identity
// Set of elements
type A
// Operations on those elements
def combine(l: A, r: A): A
val identity: A
// Laws about those operations
a <> identity == a
identity <> a == a
EASY ALGEBRA
Commutativity
// Set of elements
type A
// Operations on those elements
def combine(l: A, r: A): A
// Laws about those operations
a1 <> a2 == a2 <> a1
EASY ALGEBRA
EASY ALGEBRA
Standard Types
// Associative, commutative, identity
def combine(l: Int, r: Int): Int =
l + r
val identity: Int = 0
// Associative, identity
def combine(l: String, r: String): String =
l + r
val identity: String = “”
EASY ALGEBRA
Business Domain Specific Types
final case class Csv(
rows: Vector[Vector[String]],
headers: Map[String, Int]
)
// Associative, identity
def combine(l: Csv, r: Csv): Csv =
???
TOUR OF ZIO
PRELUDE
> PRELUDE
ZIO Prelude is a small library that brings a
common, useful algebraic abstractions & data
types to Scala developers.
ZIO Prelude is an alternative to libraries like
Scalaz and Cats based on radical ideas that
embrace modularity & subtyping in Scala and
offer new levels of power and ergonomics.
TOUR OF ZIO
PRELUDE
TOUR OF ZIO
PRELUDE
Radical Orthogonal Principled
Scala-First Minimal
Pragmatic
Accessible Opinionated
Guiding Design Principles
TOUR OF ZIO
PRELUDE Data Structures &
Patterns for
Traversing
List[A], Option[A], ...
Patterns of
Composition for
Types
(A, A) => A
Patterns of
Composition for
Type Constructors
(F[A], F[A]) => F[A]
Three Areas of Focus
TOUR OF ZIO
PRELUDE
The Anti-Modularity of the Functor Hierarchy
Functor
Applicative, Monad, etc.
Trouble starts here!
TOUR OF ZIO
PRELUDE
The Anti-Modularity of the Functor Hierarchy
Functions Composition
The Classic Functor
Hierarchy
TOUR OF ZIO
PRELUDE
The Anti-Modularity of the Functor Hierarchy
trait Monad[F[_]] extends Applicative[F] {
def map[A, B](fa: F[A])(f: A => B): F[B]
def ap[A, B](ff: F[A => B])(f: F[A]): F[B]
def pure[A](a: A): F[A]
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
}
TOUR OF ZIO
PRELUDE
Detangling Functions from Composition
trait Monad[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
def zip[A, B](fa: F[A], fb: F[B]): F[(A, B)]
def any: F[Any]
def flatten[A](fa: F[F[A]]): F[A]
}
TOUR OF ZIO
PRELUDE
The Modularity of the ZIO Prelude Hierarchy
Functions Composition
ZIO Prelude
Hierarchy
TOUR OF ZIO
PRELUDE
The Modularity of the ZIO Prelude Hierarchy
type Semigroup[A] = Associative[A]
type CommutativeSemigroup[A] = Associative[A] with Commutative[A]
type Monoid[A] = Identity[A]
type CommutativeMonoid[A] = Commutative[A] with Identity[A]
type Group[A] = Identity[A] with Inverse[A]
type AbelianGroup[A] = Commutative[A] with Identity[A] with Inverse[A]
TOUR OF ZIO
PRELUDE
The Modularity of the ZIO Prelude Hierarchy
type Functor[F[+_]] = Covariant[F]
type Contravariant[F[-_]] = zio.prelude.Contravariant[F]
type Invariant[F[_]] = zio.prelude.Invariant[F]
type Alternative[F[+_]] = Covariant[F] with IdentityBoth[F] with IdentityEither[F]
type InvariantAlt[F[_]] = Invariant[F] with IdentityBoth[F] with IdentityEither[F]
TOUR OF ZIO
PRELUDE
The Modularity of the ZIO Prelude Hierarchy
type InvariantSemigroupal[F[_]] = Invariant[F] with AssociativeBoth[F]
type Semigroupal[F[+_]] = Covariant[F] with AssociativeBoth[F]
type ContravariantSemigroupal[F[-_]] = Contravariant[F] with AssociativeBoth[F]
type SemigroupK[F[_]] = AssociativeEither[F]
type MonoidK[F[_]] = IdentityEither[F]
type ContravariantMonoidal[F[-_]] = Contravariant[F] with IdentityBoth[F]
type InvariantMonoidal[F[_]] = Invariant[F] with IdentityBoth[F]
TOUR OF ZIO
PRELUDE
The Modularity of the ZIO Prelude Hierarchy
type FlatMap[F[+_]] = Covariant[F] with AssociativeFlatten[F]
type Monad[F[+_]] = Covariant[F] with IdentityFlatten[F]
type Divide[F[-_]] = Contravariant[F] with AssociativeBoth[F]
type Divisible[F[-_]] = Contravariant[F] with IdentityBoth[F]
type Decidable[F[-_]] = Contravariant[F] with IdentityBoth[F] with IdentityEither[F]
type Apply[F[+_]] = Covariant[F] with AssociativeBoth[F]
type Applicative[F[+_]] = Covariant[F] with IdentityBoth[F]
type InvariantApplicative[F[_]] = Invariant[F] with IdentityBoth[F]
TOUR OF ZIO
PRELUDE
trait Associative[A] {
def combine(l: A, r: A): A
}
// a1 <> (a2 <> a3) == (a1 <> a2) <> a3
TOUR OF ZIO
PRELUDE
trait Identity[A] extends Associative[A] {
def combine(l: A, r: A): A
def identity: A
}
// a <> identity == a
// identity <> a == a
TOUR OF ZIO
PRELUDE
trait Commutative[A] extends Associative[A] {
def combine(l: A, r: A): A
}
// a1 <> a2 == a2 <> a1
TOUR OF ZIO
PRELUDE
trait Covariant[F[+_]] {
def map[A, B](f: A => B):
F[A] => F[B]
}
Variance Guarantees Automatic Widening
TOUR OF ZIO
PRELUDE
trait Contravariant[F[-_]] {
def contramap[A, B](f: B => A):
F[A] => F[B]
}
Variance Guarantees Automatic Narrowing
TOUR OF ZIO
PRELUDE
case class <=>[A, B](
to: A => B, from: B => A)
trait Invariant[F[_]] {
def invmap[A, B](f: A <=> B):
F[A] <=> F[B]
}
TOUR OF ZIO
PRELUDE
trait AssociativeBoth[F[_]] {
def combine[A, B](
left : F[A],
right: F[B]): F[(A, B)]
}
// zio1 zip zio2
TOUR OF ZIO
PRELUDE
trait AssociativeEither[F[_]] {
def combine[A, B](
left : F[A],
right: F[B]): F[Either[A, B]]
}
// zio1 orElseEither zio2
TOUR OF ZIO
PRELUDE
trait AssociativeFlatten[F[+_]] {
def flatten[A](nested: F[F[A]]): F[A]
}
// zio.flatten
TOUR OF ZIO
PRELUDE
trait IdentityBoth[F[_]] extends
AssociativeBoth[F] {
def combine[A, B](
left : F[A],
right: F[B]): F[(A, B)]
def any: F[Any]
}
// zio1 zip zio2
// ZIO.unit
TOUR OF ZIO
PRELUDE
trait IdentityEither[F[_]] extends
AssociativeBoth[F] {
def combine[A, B](
left : F[A],
right: F[B]): F[Either[A, B]]
def none: F[Nothing]
}
// zio1 orElseEither zio2
// ZIO.halt(Cause.empty)
TOUR OF ZIO
PRELUDE
trait IdentityFlatten[F[+_]] extends
AssociativeFlatten[F] {
def flatten[A](nested: F[F[A]]): F[A]
def any: F[Any]
}
// zio.flatten
// ZIO.unit
TOUR OF ZIO
PRELUDE
trait CommutativeBoth[F[_]] extends
AssociativeBoth[F] {
def combine[A, B](
left : F[A],
right: F[B]): F[(A, B)]
}
// zio1 zipPar zio2
TOUR OF ZIO
PRELUDE
trait CommutativeEither[F[_]] extends
AssociativeEither[F] {
def combine[A, B](
left : F[A],
right: F[B]): F[Either[A, B]]
}
// zio1 raceEither zio2
TOUR OF ZIO
PRELUDE
trait Traversable[Data[+_]] {
def foreach[Effect[_]: …, A, B](as: Data[A])(
f: A => Effect[B]): Effect[Data[B]]
}
// requests.foreach { request =>
// handleRequest(request)
// }
TOUR OF ZIO
PRELUDE
trait NonEmptyTraversable[Data[+_]] extends
Traversable[Data] {
def foreach1[Effect[_]: …, A, B](as: Data[A])(
f: A => Effect[B]): Effect[Data[B]]
}
TOUR OF ZIO
PRELUDE
Debug[-A]
Equal[-A]
Hash[-A]
Ord[-A]
Embracing Declaration-Site Variance
implicit val ordAnimal:
Ord[Animal] = …
if (dog1 <= dog2) {
// WORKS!!!
}
TOUR OF ZIO
PRELUDE
NonEmptyList[A]
Validation[E, A]
ZSet[M, A]
Embrace & Extend Scala Collections
TOUR OF ZIO
PRELUDE
trait ZPure[-StateIn, +StateOut, -Env, +Err, +Success]
type State[S, +A] = ZPure[S, S, Any, Nothing, A]
type EState[S, +E, +A] = ZPure[S, S, Any, E , A]
No More Monad Transformers
For when you think ZIO is great but just doesn’t have enough type parameters
TOUR OF ZIO
PRELUDE
type MyStack[S1, S2, R, E, A] =
Kleisli[
({ type lambda[a] =
EitherT[
({ type lambda[a] =
IndexedStateT[Eval, S1, S2, a]
})#lambda,
E,
a]
})#lambda,
R,
A]
The Alternative
TOUR OF ZIO
PRELUDE
// Monad Transformers
def get[S, R, E]: MyStack[S, S, R, E, S] = {
type SState[A] = State[S, A]
type EitherESState[A] = EitherT[SState, E, A]
val eitherT = EitherT.liftF[SState, E, S](State.get)
Kleisli.liftF[EitherESState, R, S](eitherT)
}
// ZPure
def get[S]: State[S, S] =
State.get[S]
Ergonomics
TOUR OF ZIO
PRELUDE
Performance
TOUR OF ZIO
PRELUDE
Newtypes
object Meter extends Subtype[Int]
type Meter = Meter.Type
object Sum extends SubtypeF
type Sum[A] = Sum.Type[A]
object Natural extends
NewtypeSmart[Int](isGreaterThanEqualTo(0))
type Natural = Natural.Type
TOUR OF ZIO
PRELUDE
Ergonomics
List(1, 2, 3, 4, 5).foldMap(Sum(_))
// 15
List(1, 2, 3, 4, 5).foldMap(Prod(_))
// 120
● Documentation
● More Instances
● More Polishing
● Effect Type Classes
● Performance Optimization
● Automatic Derivation for ADTs
● Get Feedback from Real Users
NEXT STEPS
SPECIAL THANKS
● Dejan Mijic
● Sken
● Manfred Weber
● Jorge Aliss
● Phil Derome
● Kamal King
● Maxim Schuwalaw
And Salar Rahmanian!
THANK YOU!
Does anyone have any questions?
github.com/zio/zio-prelude
Get mentored: patreon.com/jdegoes
Follow us: @jdegoes, @adamfraser

Contenu connexe

Tendances

ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaWiem Zine Elabidine
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and EffectsMartin Odersky
 
The Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldThe Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldPhilip Schwarz
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsPhilip Schwarz
 
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
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
 
ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022Alexander Ioffe
 
Taking your side effects aside
Taking your side effects asideTaking your side effects aside
Taking your side effects aside💡 Tomasz Kogut
 
Implementing the IO Monad in Scala
Implementing the IO Monad in ScalaImplementing the IO Monad in Scala
Implementing the IO Monad in ScalaHermann Hueck
 
The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...Philip Schwarz
 
Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Philip Schwarz
 
Purely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaPurely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaVladimir Kostyukov
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed worldDebasish Ghosh
 
Object-oriented programming
Object-oriented programmingObject-oriented programming
Object-oriented programmingNeelesh Shukla
 
Programación Funcional 101 con Scala y ZIO 2.0
Programación Funcional 101 con Scala y ZIO 2.0Programación Funcional 101 con Scala y ZIO 2.0
Programación Funcional 101 con Scala y ZIO 2.0Jorge Vásquez
 
Peeking inside the engine of ZIO SQL.pdf
Peeking inside the engine of ZIO SQL.pdfPeeking inside the engine of ZIO SQL.pdf
Peeking inside the engine of ZIO SQL.pdfJaroslavRegec1
 
Functional programming
Functional programmingFunctional programming
Functional programmingijcd
 

Tendances (20)

Preparing for Scala 3
Preparing for Scala 3Preparing for Scala 3
Preparing for Scala 3
 
ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in Scala
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and Effects
 
The Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldThe Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and Fold
 
Applicative style programming
Applicative style programmingApplicative style programming
Applicative style programming
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and Cats
 
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
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
 
ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022
 
Taking your side effects aside
Taking your side effects asideTaking your side effects aside
Taking your side effects aside
 
Implementing the IO Monad in Scala
Implementing the IO Monad in ScalaImplementing the IO Monad in Scala
Implementing the IO Monad in Scala
 
The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...
 
Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Sequence and Traverse - Part 2
Sequence and Traverse - Part 2
 
Purely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaPurely Functional Data Structures in Scala
Purely Functional Data Structures in Scala
 
Zio in real world
Zio in real worldZio in real world
Zio in real world
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
 
Object-oriented programming
Object-oriented programmingObject-oriented programming
Object-oriented programming
 
Object Oriented Programming
Object Oriented ProgrammingObject Oriented Programming
Object Oriented Programming
 
Programación Funcional 101 con Scala y ZIO 2.0
Programación Funcional 101 con Scala y ZIO 2.0Programación Funcional 101 con Scala y ZIO 2.0
Programación Funcional 101 con Scala y ZIO 2.0
 
Peeking inside the engine of ZIO SQL.pdf
Peeking inside the engine of ZIO SQL.pdfPeeking inside the engine of ZIO SQL.pdf
Peeking inside the engine of ZIO SQL.pdf
 
Functional programming
Functional programmingFunctional programming
Functional programming
 

Similaire à Refactoring Functional Type Classes

Type class survival guide
Type class survival guideType class survival guide
Type class survival guideMark Canlas
 
Oh, All the things you'll traverse
Oh, All the things you'll traverseOh, All the things you'll traverse
Oh, All the things you'll traverseLuka Jacobowitz
 
Fp in scala part 1
Fp in scala part 1Fp in scala part 1
Fp in scala part 1Hang Zhao
 
Algebraic Data Types and Origami Patterns
Algebraic Data Types and Origami PatternsAlgebraic Data Types and Origami Patterns
Algebraic Data Types and Origami PatternsVasil Remeniuk
 
Why functional why scala
Why functional  why scala Why functional  why scala
Why functional why scala Neville Li
 
Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Philip Schwarz
 
Fp in scala with adts part 2
Fp in scala with adts part 2Fp in scala with adts part 2
Fp in scala with adts part 2Hang Zhao
 
Functors, in theory and in practice
Functors, in theory and in practiceFunctors, in theory and in practice
Functors, in theory and in practiceMartin Menestret
 
Drinking the free kool-aid
Drinking the free kool-aidDrinking the free kool-aid
Drinking the free kool-aidDavid Hoyt
 
Monoids, Monoids, Monoids - ScalaLove 2020
Monoids, Monoids, Monoids - ScalaLove 2020Monoids, Monoids, Monoids - ScalaLove 2020
Monoids, Monoids, Monoids - ScalaLove 2020Luka Jacobowitz
 
2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf
2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf
2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdfAndrey Breslav
 
Practical Functional Programming Presentation by Bogdan Hodorog
Practical Functional Programming Presentation by Bogdan HodorogPractical Functional Programming Presentation by Bogdan Hodorog
Practical Functional Programming Presentation by Bogdan Hodorog3Pillar Global
 
Types by Adform Research
Types by Adform ResearchTypes by Adform Research
Types by Adform ResearchVasil Remeniuk
 
Category theory for beginners
Category theory for beginnersCategory theory for beginners
Category theory for beginnerskenbot
 
Automatic Type Class Derivation with Shapeless
Automatic Type Class Derivation with ShapelessAutomatic Type Class Derivation with Shapeless
Automatic Type Class Derivation with Shapelessjcazevedo
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patternsleague
 
Introduction to Functional Languages
Introduction to Functional LanguagesIntroduction to Functional Languages
Introduction to Functional Languagessuthi
 

Similaire à Refactoring Functional Type Classes (20)

Type class survival guide
Type class survival guideType class survival guide
Type class survival guide
 
Oh, All the things you'll traverse
Oh, All the things you'll traverseOh, All the things you'll traverse
Oh, All the things you'll traverse
 
Fp in scala part 1
Fp in scala part 1Fp in scala part 1
Fp in scala part 1
 
Algebraic Data Types and Origami Patterns
Algebraic Data Types and Origami PatternsAlgebraic Data Types and Origami Patterns
Algebraic Data Types and Origami Patterns
 
Why functional why scala
Why functional  why scala Why functional  why scala
Why functional why scala
 
Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3
 
Fp in scala with adts part 2
Fp in scala with adts part 2Fp in scala with adts part 2
Fp in scala with adts part 2
 
Functors, in theory and in practice
Functors, in theory and in practiceFunctors, in theory and in practice
Functors, in theory and in practice
 
Drinking the free kool-aid
Drinking the free kool-aidDrinking the free kool-aid
Drinking the free kool-aid
 
Monoids, Monoids, Monoids - ScalaLove 2020
Monoids, Monoids, Monoids - ScalaLove 2020Monoids, Monoids, Monoids - ScalaLove 2020
Monoids, Monoids, Monoids - ScalaLove 2020
 
2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf
2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf
2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf
 
Scala jargon cheatsheet
Scala jargon cheatsheetScala jargon cheatsheet
Scala jargon cheatsheet
 
Practical Functional Programming Presentation by Bogdan Hodorog
Practical Functional Programming Presentation by Bogdan HodorogPractical Functional Programming Presentation by Bogdan Hodorog
Practical Functional Programming Presentation by Bogdan Hodorog
 
Types by Adform Research
Types by Adform ResearchTypes by Adform Research
Types by Adform Research
 
Typeclasses
TypeclassesTypeclasses
Typeclasses
 
Category theory for beginners
Category theory for beginnersCategory theory for beginners
Category theory for beginners
 
Automatic Type Class Derivation with Shapeless
Automatic Type Class Derivation with ShapelessAutomatic Type Class Derivation with Shapeless
Automatic Type Class Derivation with Shapeless
 
Monad Fact #4
Monad Fact #4Monad Fact #4
Monad Fact #4
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
 
Introduction to Functional Languages
Introduction to Functional LanguagesIntroduction to Functional Languages
Introduction to Functional Languages
 

Plus de John De Goes

One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them AllJohn De Goes
 
Atomically { Delete Your Actors }
Atomically { Delete Your Actors }Atomically { Delete Your Actors }
Atomically { Delete Your Actors }John De Goes
 
The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final TaglessJohn De Goes
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: RebirthJohn De Goes
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: RebirthJohn De Goes
 
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018John De Goes
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New GameJohn De Goes
 
Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsJohn De Goes
 
Orthogonal Functional Architecture
Orthogonal Functional ArchitectureOrthogonal Functional Architecture
Orthogonal Functional ArchitectureJohn De Goes
 
The Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect SystemThe Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect SystemJohn De Goes
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
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
 
Post-Free: Life After Free Monads
Post-Free: Life After Free MonadsPost-Free: Life After Free Monads
Post-Free: Life After Free MonadsJohn De Goes
 
Streams for (Co)Free!
Streams for (Co)Free!Streams for (Co)Free!
Streams for (Co)Free!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...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...John De Goes
 
Halogen: Past, Present, and Future
Halogen: Past, Present, and FutureHalogen: Past, Present, and Future
Halogen: Past, Present, and FutureJohn De Goes
 
All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!John De Goes
 
Getting Started with PureScript
Getting Started with PureScriptGetting Started with PureScript
Getting Started with PureScriptJohn De Goes
 
SlamData - How MongoDB Is Powering a Revolution in Visual Analytics
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 AnalyticsJohn De Goes
 

Plus de John De Goes (20)

One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them All
 
Atomically { Delete Your Actors }
Atomically { Delete Your Actors }Atomically { Delete Your Actors }
Atomically { Delete Your Actors }
 
The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final Tagless
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
 
ZIO Queue
ZIO QueueZIO Queue
ZIO Queue
 
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New Game
 
Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka Actors
 
Orthogonal Functional Architecture
Orthogonal Functional ArchitectureOrthogonal Functional Architecture
Orthogonal Functional Architecture
 
The Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect SystemThe Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect System
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
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 & Analytics
 
Post-Free: Life After Free Monads
Post-Free: Life After Free MonadsPost-Free: Life After Free Monads
Post-Free: Life After Free Monads
 
Streams for (Co)Free!
Streams for (Co)Free!Streams for (Co)Free!
Streams for (Co)Free!
 
MTL Versus Free
MTL Versus FreeMTL Versus Free
MTL Versus Free
 
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...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
 
Halogen: Past, Present, and Future
Halogen: Past, Present, and FutureHalogen: Past, Present, and Future
Halogen: Past, Present, and Future
 
All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!
 
Getting Started with PureScript
Getting Started with PureScriptGetting Started with PureScript
Getting Started with PureScript
 
SlamData - How MongoDB Is Powering a Revolution in Visual Analytics
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
 

Dernier

Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 

Dernier (20)

Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 

Refactoring Functional Type Classes

  • 1. SF Scala Meetup - July 30, 2020 John A. De Goes — @jdegoes Adam Fraser — @adamfraser Refactoring Functional Type Classes
  • 2. WHY YOU’RE HERE “Let me tell you why you’re here. You’re here because you know something. What you know you can’t explain, but you feel it. You’ve felt it your entire life, that there’s something wrong with the world. You don’t know what it is, but it’s there, like a splinter in your mind, driving you mad. It is this feeling that has brought you to me. Do you know what I’m talking about?” — Morpheus, The Matrix
  • 3. TABLE OF CONTENTS 01 THE LEGEND OF FUNCTOR The supreme reign of the Haskell functor hierarchy 02 TROUBLE IN FUNCTOR TOWN Drawbacks of the classic functor hierarchy 03 EASY ALGEBRA Unlike category theory, you already know algebra 04 TOUR OF ZIO PRELUDE An algebraic, modular, & Scala-first basis for type classes
  • 5. Functor THE LEGEND OF FUNCTOR trait Functor[F[_]] { def map[A, B](fa: F[A])(f: A => B): F[B] }
  • 6. Functor -> Apply THE LEGEND OF FUNCTOR trait Apply[F[_]] extends Functor[F] { def map[A, B](fa: F[A])(f: A => B): F[B] def ap[A, B](ff: F[A => B])(f: F[A]): F[B] }
  • 7. Functor -> Apply -> Applicative THE LEGEND OF FUNCTOR trait Applicative[F[_]] extends Apply[F] { def map[A, B](fa: F[A])(f: A => B): F[B] def ap[A, B](ff: F[A => B])(f: F[A]): F[B] def pure[A](a: A): F[A] }
  • 8. Functor -> Apply -> Applicative -> Monad THE LEGEND OF FUNCTOR trait Monad[F[_]] extends Applicative[F] { def map[A, B](fa: F[A])(f: A => B): F[B] def ap[A, B](ff: F[A => B])(f: F[A]): F[B] def pure[A](a: A): F[A] def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] } *Bind is skipped.
  • 9. THE LEGEND OF FUNCTOR The Ubiquity of Functor in Functional Programming ● Haskell ● Scala ○ Scalaz ○ Cats ● Kotlin ● Java ● F# ● Idris ● And many others! 9
  • 10. Books Have Been Written About It THE LEGEND OF FUNCTOR
  • 12. The Curse of Haskellisms TROUBLE IN FUNCTOR TOWN def ap[A, B]( ff: F[A => B], fa: F[A]): F[B] f :: Int -> Int -> Int -> Int f <$> arg1 <*> arg2 <*> arg3
  • 13. Set Is Not A “Functor”? TROUBLE IN FUNCTOR TOWN set.map(f).map(g) set.map(f andThen g) f g f.andThen(g) A B C A C
  • 14. The Functor Hierarchy Is A Lie! TROUBLE IN FUNCTOR TOWN Functor in FP Functor in Math
  • 15. ZIO Config TROUBLE IN FUNCTOR TOWN (string(“server”) |@| int(“port”))( Config.apply(_), Config.unapply(_))
  • 16. ZIO Codec TROUBLE IN FUNCTOR TOWN lazy val js: Codec[Val] = ((spacing, ()) ~> (obj | arr | str | `true` | `false` | `null` | num) <~ ((), spacing))
  • 17. Introspectable Monads TROUBLE IN FUNCTOR TOWN for { bool <- boolParser value <- if (bool) parserA else parserB } yield value
  • 18. Constrained DSLs TROUBLE IN FUNCTOR TOWN def map[A, B](fa: F[A])(f: A => B): F[B] val fa: F[A] = … val f : A => B = … fa.map(a => f(a)) Type B is unconstrainable!
  • 19. Invariance Pain TROUBLE IN FUNCTOR TOWN val functorDog: F[Dog] = … val functorAnimal: F[Animal] = functorDog ERROR!!!
  • 20. Invariance Pain TROUBLE IN FUNCTOR TOWN val functorDog: F[Dog] = … val functorAnimal: F[Animal] = functorDog.widen[Animal]
  • 21. Stack-Exploding Strictness TROUBLE IN FUNCTOR TOWN def forever[A](fa: F[A]): F[A] = fa *> forever(fa)
  • 22. Lawless Type Classes & Operations TROUBLE IN FUNCTOR TOWN Defer Foldable Monad#tailRecM Parallel NonEmptyParallel UnorderedFoldable
  • 23. Type Class Proliferation TROUBLE IN FUNCTOR TOWN Align Alternative Always Applicative ApplicativeError Apply Bifoldable Bifunctor Bimonad Bitraverse CoflatMap CommutativeApplicative CommutativeApply CommutativeFlatMap CommutativeMonad Comonad Contravariant ContravariantMonoidal ContravariantSemigroupal Defer Distributive Eval EvalGroup EvalMonoid EvalSemigroup FlatMap Foldable Functor FunctorFilter Inject InjectK Invariant InvariantMonoidal InvariantSemigroupal Later Monad MonadError MonoidK NonEmptyParallelNonEmptyR educible NonEmptyTraverse NotNull Now Parallel Reducible Representable SemigroupK Semigroupal Show StackSafeMonad Traverse TraverseFilter UnorderedFoldable UnorderedTraverse
  • 24. Type Class Proliferation TROUBLE IN FUNCTOR TOWN Align Alternative Always Applicative ApplicativeError Apply Bifoldable Bifunctor Bimonad Bitraverse CoflatMap CommutativeApplicative CommutativeApply CommutativeFlatMap CommutativeMonad Comonad Contravariant ContravariantMonoidal ContravariantSemigroupal Defer Distributive Eval EvalGroup EvalMonoid EvalSemigroup FlatMap Foldable Functor FunctorFilter Inject InjectK Invariant InvariantMonoidal InvariantSemigroupal Later Monad MonadError MonoidK NonEmptyParallelNonEmptyR educible NonEmptyTraverse NotNull Now Parallel Reducible Representable SemigroupK Semigroupal Show StackSafeMonad Traverse TraverseFilter UnorderedFoldable UnorderedTraverse *meme from dev.to
  • 25. Maddening Monad Transformers TROUBLE IN FUNCTOR TOWN type MyApp[E, W, S, R, A] = OptionT[ EitherT[ WriterT[ StateT[ Kleisli[Task, R, *], S, *], W, *], E, *], *]
  • 26. TROUBLE IN FUNCTOR TOWN Is There Another Way?
  • 28. EASY ALGEBRA // Set of elements type Int // Operations on those elements def plus(x: Int, y: Int): Int // Laws about those operations x + (y + z) == (x + y) + z x + y == y + x You Already Know This
  • 29. EASY ALGEBRA Associativity // Set of elements type A // Operations on those elements def combine(l: A, r: A): A // Laws about those operations a1 <> (a2 <> a3) == (a1 <> a2) <> a3
  • 30. EASY ALGEBRA Identity // Set of elements type A // Operations on those elements def combine(l: A, r: A): A val identity: A // Laws about those operations a <> identity == a identity <> a == a
  • 31. EASY ALGEBRA Commutativity // Set of elements type A // Operations on those elements def combine(l: A, r: A): A // Laws about those operations a1 <> a2 == a2 <> a1
  • 33. EASY ALGEBRA Standard Types // Associative, commutative, identity def combine(l: Int, r: Int): Int = l + r val identity: Int = 0 // Associative, identity def combine(l: String, r: String): String = l + r val identity: String = “”
  • 34. EASY ALGEBRA Business Domain Specific Types final case class Csv( rows: Vector[Vector[String]], headers: Map[String, Int] ) // Associative, identity def combine(l: Csv, r: Csv): Csv = ???
  • 36. ZIO Prelude is a small library that brings a common, useful algebraic abstractions & data types to Scala developers. ZIO Prelude is an alternative to libraries like Scalaz and Cats based on radical ideas that embrace modularity & subtyping in Scala and offer new levels of power and ergonomics. TOUR OF ZIO PRELUDE
  • 37. TOUR OF ZIO PRELUDE Radical Orthogonal Principled Scala-First Minimal Pragmatic Accessible Opinionated Guiding Design Principles
  • 38. TOUR OF ZIO PRELUDE Data Structures & Patterns for Traversing List[A], Option[A], ... Patterns of Composition for Types (A, A) => A Patterns of Composition for Type Constructors (F[A], F[A]) => F[A] Three Areas of Focus
  • 39. TOUR OF ZIO PRELUDE The Anti-Modularity of the Functor Hierarchy Functor Applicative, Monad, etc. Trouble starts here!
  • 40. TOUR OF ZIO PRELUDE The Anti-Modularity of the Functor Hierarchy Functions Composition The Classic Functor Hierarchy
  • 41. TOUR OF ZIO PRELUDE The Anti-Modularity of the Functor Hierarchy trait Monad[F[_]] extends Applicative[F] { def map[A, B](fa: F[A])(f: A => B): F[B] def ap[A, B](ff: F[A => B])(f: F[A]): F[B] def pure[A](a: A): F[A] def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] }
  • 42. TOUR OF ZIO PRELUDE Detangling Functions from Composition trait Monad[F[_]] { def map[A, B](fa: F[A])(f: A => B): F[B] def zip[A, B](fa: F[A], fb: F[B]): F[(A, B)] def any: F[Any] def flatten[A](fa: F[F[A]]): F[A] }
  • 43. TOUR OF ZIO PRELUDE The Modularity of the ZIO Prelude Hierarchy Functions Composition ZIO Prelude Hierarchy
  • 44. TOUR OF ZIO PRELUDE The Modularity of the ZIO Prelude Hierarchy type Semigroup[A] = Associative[A] type CommutativeSemigroup[A] = Associative[A] with Commutative[A] type Monoid[A] = Identity[A] type CommutativeMonoid[A] = Commutative[A] with Identity[A] type Group[A] = Identity[A] with Inverse[A] type AbelianGroup[A] = Commutative[A] with Identity[A] with Inverse[A]
  • 45. TOUR OF ZIO PRELUDE The Modularity of the ZIO Prelude Hierarchy type Functor[F[+_]] = Covariant[F] type Contravariant[F[-_]] = zio.prelude.Contravariant[F] type Invariant[F[_]] = zio.prelude.Invariant[F] type Alternative[F[+_]] = Covariant[F] with IdentityBoth[F] with IdentityEither[F] type InvariantAlt[F[_]] = Invariant[F] with IdentityBoth[F] with IdentityEither[F]
  • 46. TOUR OF ZIO PRELUDE The Modularity of the ZIO Prelude Hierarchy type InvariantSemigroupal[F[_]] = Invariant[F] with AssociativeBoth[F] type Semigroupal[F[+_]] = Covariant[F] with AssociativeBoth[F] type ContravariantSemigroupal[F[-_]] = Contravariant[F] with AssociativeBoth[F] type SemigroupK[F[_]] = AssociativeEither[F] type MonoidK[F[_]] = IdentityEither[F] type ContravariantMonoidal[F[-_]] = Contravariant[F] with IdentityBoth[F] type InvariantMonoidal[F[_]] = Invariant[F] with IdentityBoth[F]
  • 47. TOUR OF ZIO PRELUDE The Modularity of the ZIO Prelude Hierarchy type FlatMap[F[+_]] = Covariant[F] with AssociativeFlatten[F] type Monad[F[+_]] = Covariant[F] with IdentityFlatten[F] type Divide[F[-_]] = Contravariant[F] with AssociativeBoth[F] type Divisible[F[-_]] = Contravariant[F] with IdentityBoth[F] type Decidable[F[-_]] = Contravariant[F] with IdentityBoth[F] with IdentityEither[F] type Apply[F[+_]] = Covariant[F] with AssociativeBoth[F] type Applicative[F[+_]] = Covariant[F] with IdentityBoth[F] type InvariantApplicative[F[_]] = Invariant[F] with IdentityBoth[F]
  • 48. TOUR OF ZIO PRELUDE trait Associative[A] { def combine(l: A, r: A): A } // a1 <> (a2 <> a3) == (a1 <> a2) <> a3
  • 49. TOUR OF ZIO PRELUDE trait Identity[A] extends Associative[A] { def combine(l: A, r: A): A def identity: A } // a <> identity == a // identity <> a == a
  • 50. TOUR OF ZIO PRELUDE trait Commutative[A] extends Associative[A] { def combine(l: A, r: A): A } // a1 <> a2 == a2 <> a1
  • 51. TOUR OF ZIO PRELUDE trait Covariant[F[+_]] { def map[A, B](f: A => B): F[A] => F[B] } Variance Guarantees Automatic Widening
  • 52. TOUR OF ZIO PRELUDE trait Contravariant[F[-_]] { def contramap[A, B](f: B => A): F[A] => F[B] } Variance Guarantees Automatic Narrowing
  • 53. TOUR OF ZIO PRELUDE case class <=>[A, B]( to: A => B, from: B => A) trait Invariant[F[_]] { def invmap[A, B](f: A <=> B): F[A] <=> F[B] }
  • 54. TOUR OF ZIO PRELUDE trait AssociativeBoth[F[_]] { def combine[A, B]( left : F[A], right: F[B]): F[(A, B)] } // zio1 zip zio2
  • 55. TOUR OF ZIO PRELUDE trait AssociativeEither[F[_]] { def combine[A, B]( left : F[A], right: F[B]): F[Either[A, B]] } // zio1 orElseEither zio2
  • 56. TOUR OF ZIO PRELUDE trait AssociativeFlatten[F[+_]] { def flatten[A](nested: F[F[A]]): F[A] } // zio.flatten
  • 57. TOUR OF ZIO PRELUDE trait IdentityBoth[F[_]] extends AssociativeBoth[F] { def combine[A, B]( left : F[A], right: F[B]): F[(A, B)] def any: F[Any] } // zio1 zip zio2 // ZIO.unit
  • 58. TOUR OF ZIO PRELUDE trait IdentityEither[F[_]] extends AssociativeBoth[F] { def combine[A, B]( left : F[A], right: F[B]): F[Either[A, B]] def none: F[Nothing] } // zio1 orElseEither zio2 // ZIO.halt(Cause.empty)
  • 59. TOUR OF ZIO PRELUDE trait IdentityFlatten[F[+_]] extends AssociativeFlatten[F] { def flatten[A](nested: F[F[A]]): F[A] def any: F[Any] } // zio.flatten // ZIO.unit
  • 60. TOUR OF ZIO PRELUDE trait CommutativeBoth[F[_]] extends AssociativeBoth[F] { def combine[A, B]( left : F[A], right: F[B]): F[(A, B)] } // zio1 zipPar zio2
  • 61. TOUR OF ZIO PRELUDE trait CommutativeEither[F[_]] extends AssociativeEither[F] { def combine[A, B]( left : F[A], right: F[B]): F[Either[A, B]] } // zio1 raceEither zio2
  • 62. TOUR OF ZIO PRELUDE trait Traversable[Data[+_]] { def foreach[Effect[_]: …, A, B](as: Data[A])( f: A => Effect[B]): Effect[Data[B]] } // requests.foreach { request => // handleRequest(request) // }
  • 63. TOUR OF ZIO PRELUDE trait NonEmptyTraversable[Data[+_]] extends Traversable[Data] { def foreach1[Effect[_]: …, A, B](as: Data[A])( f: A => Effect[B]): Effect[Data[B]] }
  • 64. TOUR OF ZIO PRELUDE Debug[-A] Equal[-A] Hash[-A] Ord[-A] Embracing Declaration-Site Variance implicit val ordAnimal: Ord[Animal] = … if (dog1 <= dog2) { // WORKS!!! }
  • 65. TOUR OF ZIO PRELUDE NonEmptyList[A] Validation[E, A] ZSet[M, A] Embrace & Extend Scala Collections
  • 66. TOUR OF ZIO PRELUDE trait ZPure[-StateIn, +StateOut, -Env, +Err, +Success] type State[S, +A] = ZPure[S, S, Any, Nothing, A] type EState[S, +E, +A] = ZPure[S, S, Any, E , A] No More Monad Transformers For when you think ZIO is great but just doesn’t have enough type parameters
  • 67. TOUR OF ZIO PRELUDE type MyStack[S1, S2, R, E, A] = Kleisli[ ({ type lambda[a] = EitherT[ ({ type lambda[a] = IndexedStateT[Eval, S1, S2, a] })#lambda, E, a] })#lambda, R, A] The Alternative
  • 68. TOUR OF ZIO PRELUDE // Monad Transformers def get[S, R, E]: MyStack[S, S, R, E, S] = { type SState[A] = State[S, A] type EitherESState[A] = EitherT[SState, E, A] val eitherT = EitherT.liftF[SState, E, S](State.get) Kleisli.liftF[EitherESState, R, S](eitherT) } // ZPure def get[S]: State[S, S] = State.get[S] Ergonomics
  • 70. TOUR OF ZIO PRELUDE Newtypes object Meter extends Subtype[Int] type Meter = Meter.Type object Sum extends SubtypeF type Sum[A] = Sum.Type[A] object Natural extends NewtypeSmart[Int](isGreaterThanEqualTo(0)) type Natural = Natural.Type
  • 71. TOUR OF ZIO PRELUDE Ergonomics List(1, 2, 3, 4, 5).foldMap(Sum(_)) // 15 List(1, 2, 3, 4, 5).foldMap(Prod(_)) // 120
  • 72. ● Documentation ● More Instances ● More Polishing ● Effect Type Classes ● Performance Optimization ● Automatic Derivation for ADTs ● Get Feedback from Real Users NEXT STEPS
  • 73. SPECIAL THANKS ● Dejan Mijic ● Sken ● Manfred Weber ● Jorge Aliss ● Phil Derome ● Kamal King ● Maxim Schuwalaw And Salar Rahmanian!
  • 74. THANK YOU! Does anyone have any questions? github.com/zio/zio-prelude Get mentored: patreon.com/jdegoes Follow us: @jdegoes, @adamfraser