SlideShare a Scribd company logo
1 of 74
Download to read offline
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

More Related Content

What's hot

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
 
A Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOA Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOJorge Vásquez
 
Functional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldFunctional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldJorge Vásquez
 
Functors, Applicatives and Monads In Scala
Functors, Applicatives and Monads In ScalaFunctors, Applicatives and Monads In Scala
Functors, Applicatives and Monads In ScalaKnoldus Inc.
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and EffectsMartin Odersky
 
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
 
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
 
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021Natan Silnitsky
 
Functional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 WayFunctional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 WayDebasish Ghosh
 
Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Piotr Paradziński
 
Quill vs Slick Smackdown
Quill vs Slick SmackdownQuill vs Slick Smackdown
Quill vs Slick SmackdownAlexander Ioffe
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with GroovyArturo Herrero
 
Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackGaryCoady
 
Introduction to programming with ZIO functional effects
Introduction to programming with ZIO functional effectsIntroduction to programming with ZIO functional effects
Introduction to programming with ZIO functional effectsJorge Vásquez
 
Utilizing kotlin flows in an android application
Utilizing kotlin flows in an android applicationUtilizing kotlin flows in an android application
Utilizing kotlin flows in an android applicationSeven Peaks Speaks
 
Functor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadOliver Daff
 
The Power of Composition
The Power of CompositionThe Power of Composition
The Power of CompositionScott Wlaschin
 
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
 
Property Based Testing in PHP
Property Based Testing in PHPProperty Based Testing in PHP
Property Based Testing in PHPvinaikopp
 

What's hot (20)

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
 
A Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOA Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIO
 
Functional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldFunctional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorld
 
Functors, Applicatives and Monads In Scala
Functors, Applicatives and Monads In ScalaFunctors, Applicatives and Monads In Scala
Functors, Applicatives and Monads In Scala
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and Effects
 
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...
 
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
 
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
 
Functional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 WayFunctional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 Way
 
Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...
 
Quill vs Slick Smackdown
Quill vs Slick SmackdownQuill vs Slick Smackdown
Quill vs Slick Smackdown
 
Zio in real world
Zio in real worldZio in real world
Zio in real world
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web Stack
 
Introduction to programming with ZIO functional effects
Introduction to programming with ZIO functional effectsIntroduction to programming with ZIO functional effects
Introduction to programming with ZIO functional effects
 
Utilizing kotlin flows in an android application
Utilizing kotlin flows in an android applicationUtilizing kotlin flows in an android application
Utilizing kotlin flows in an android application
 
Functor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And Monad
 
The Power of Composition
The Power of CompositionThe Power of Composition
The Power of Composition
 
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
 
Property Based Testing in PHP
Property Based Testing in PHPProperty Based Testing in PHP
Property Based Testing in PHP
 

Similar to 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
 
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
 
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
 

Similar to 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
 
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
 
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
 

More from 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
 
Error Management: Future vs ZIO
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIOJohn 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
 
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
 
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
 

More from 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
 
Error Management: Future vs ZIO
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIO
 
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 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
 
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
 

Recently uploaded

UiPath Studio Web workshop series - Day 1
UiPath Studio Web workshop series  - Day 1UiPath Studio Web workshop series  - Day 1
UiPath Studio Web workshop series - Day 1DianaGray10
 
Flow Control | Block Size | ST Min | First Frame
Flow Control | Block Size | ST Min | First FrameFlow Control | Block Size | ST Min | First Frame
Flow Control | Block Size | ST Min | First FrameKapil Thakar
 
Stobox 4: Revolutionizing Investment in Real-World Assets Through Tokenization
Stobox 4: Revolutionizing Investment in Real-World Assets Through TokenizationStobox 4: Revolutionizing Investment in Real-World Assets Through Tokenization
Stobox 4: Revolutionizing Investment in Real-World Assets Through TokenizationStobox
 
Outage Analysis: March 5th/6th 2024 Meta, Comcast, and LinkedIn
Outage Analysis: March 5th/6th 2024 Meta, Comcast, and LinkedInOutage Analysis: March 5th/6th 2024 Meta, Comcast, and LinkedIn
Outage Analysis: March 5th/6th 2024 Meta, Comcast, and LinkedInThousandEyes
 
March Patch Tuesday
March Patch TuesdayMarch Patch Tuesday
March Patch TuesdayIvanti
 
From the origin to the future of Open Source model and business
From the origin to the future of  Open Source model and businessFrom the origin to the future of  Open Source model and business
From the origin to the future of Open Source model and businessFrancesco Corti
 
Automation Ops Series: Session 2 - Governance for UiPath projects
Automation Ops Series: Session 2 - Governance for UiPath projectsAutomation Ops Series: Session 2 - Governance for UiPath projects
Automation Ops Series: Session 2 - Governance for UiPath projectsDianaGray10
 
LF Energy Webinar - Unveiling OpenEEMeter 4.0
LF Energy Webinar - Unveiling OpenEEMeter 4.0LF Energy Webinar - Unveiling OpenEEMeter 4.0
LF Energy Webinar - Unveiling OpenEEMeter 4.0DanBrown980551
 
Top 10 Squarespace Development Companies
Top 10 Squarespace Development CompaniesTop 10 Squarespace Development Companies
Top 10 Squarespace Development CompaniesTopCSSGallery
 
How to become a GDSC Lead GDSC MI AOE.pptx
How to become a GDSC Lead GDSC MI AOE.pptxHow to become a GDSC Lead GDSC MI AOE.pptx
How to become a GDSC Lead GDSC MI AOE.pptxKaustubhBhavsar6
 
Emil Eifrem at GraphSummit Copenhagen 2024 - The Art of the Possible.pptx
Emil Eifrem at GraphSummit Copenhagen 2024 - The Art of the Possible.pptxEmil Eifrem at GraphSummit Copenhagen 2024 - The Art of the Possible.pptx
Emil Eifrem at GraphSummit Copenhagen 2024 - The Art of the Possible.pptxNeo4j
 
The Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightThe Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightSafe Software
 
Q4 2023 Quarterly Investor Presentation - FINAL - v1.pdf
Q4 2023 Quarterly Investor Presentation - FINAL - v1.pdfQ4 2023 Quarterly Investor Presentation - FINAL - v1.pdf
Q4 2023 Quarterly Investor Presentation - FINAL - v1.pdfTejal81
 
Novo Nordisk's journey in developing an open-source application on Neo4j
Novo Nordisk's journey in developing an open-source application on Neo4jNovo Nordisk's journey in developing an open-source application on Neo4j
Novo Nordisk's journey in developing an open-source application on Neo4jNeo4j
 
AI Workshops at Computers In Libraries 2024
AI Workshops at Computers In Libraries 2024AI Workshops at Computers In Libraries 2024
AI Workshops at Computers In Libraries 2024Brian Pichman
 
UiPath Studio Web workshop series - Day 2
UiPath Studio Web workshop series - Day 2UiPath Studio Web workshop series - Day 2
UiPath Studio Web workshop series - Day 2DianaGray10
 
How to release an Open Source Dataweave Library
How to release an Open Source Dataweave LibraryHow to release an Open Source Dataweave Library
How to release an Open Source Dataweave Libraryshyamraj55
 
Oracle Database 23c Security New Features.pptx
Oracle Database 23c Security New Features.pptxOracle Database 23c Security New Features.pptx
Oracle Database 23c Security New Features.pptxSatishbabu Gunukula
 
Introduction - IPLOOK NETWORKS CO., LTD.
Introduction - IPLOOK NETWORKS CO., LTD.Introduction - IPLOOK NETWORKS CO., LTD.
Introduction - IPLOOK NETWORKS CO., LTD.IPLOOK Networks
 
TrustArc Webinar - How to Live in a Post Third-Party Cookie World
TrustArc Webinar - How to Live in a Post Third-Party Cookie WorldTrustArc Webinar - How to Live in a Post Third-Party Cookie World
TrustArc Webinar - How to Live in a Post Third-Party Cookie WorldTrustArc
 

Recently uploaded (20)

UiPath Studio Web workshop series - Day 1
UiPath Studio Web workshop series  - Day 1UiPath Studio Web workshop series  - Day 1
UiPath Studio Web workshop series - Day 1
 
Flow Control | Block Size | ST Min | First Frame
Flow Control | Block Size | ST Min | First FrameFlow Control | Block Size | ST Min | First Frame
Flow Control | Block Size | ST Min | First Frame
 
Stobox 4: Revolutionizing Investment in Real-World Assets Through Tokenization
Stobox 4: Revolutionizing Investment in Real-World Assets Through TokenizationStobox 4: Revolutionizing Investment in Real-World Assets Through Tokenization
Stobox 4: Revolutionizing Investment in Real-World Assets Through Tokenization
 
Outage Analysis: March 5th/6th 2024 Meta, Comcast, and LinkedIn
Outage Analysis: March 5th/6th 2024 Meta, Comcast, and LinkedInOutage Analysis: March 5th/6th 2024 Meta, Comcast, and LinkedIn
Outage Analysis: March 5th/6th 2024 Meta, Comcast, and LinkedIn
 
March Patch Tuesday
March Patch TuesdayMarch Patch Tuesday
March Patch Tuesday
 
From the origin to the future of Open Source model and business
From the origin to the future of  Open Source model and businessFrom the origin to the future of  Open Source model and business
From the origin to the future of Open Source model and business
 
Automation Ops Series: Session 2 - Governance for UiPath projects
Automation Ops Series: Session 2 - Governance for UiPath projectsAutomation Ops Series: Session 2 - Governance for UiPath projects
Automation Ops Series: Session 2 - Governance for UiPath projects
 
LF Energy Webinar - Unveiling OpenEEMeter 4.0
LF Energy Webinar - Unveiling OpenEEMeter 4.0LF Energy Webinar - Unveiling OpenEEMeter 4.0
LF Energy Webinar - Unveiling OpenEEMeter 4.0
 
Top 10 Squarespace Development Companies
Top 10 Squarespace Development CompaniesTop 10 Squarespace Development Companies
Top 10 Squarespace Development Companies
 
How to become a GDSC Lead GDSC MI AOE.pptx
How to become a GDSC Lead GDSC MI AOE.pptxHow to become a GDSC Lead GDSC MI AOE.pptx
How to become a GDSC Lead GDSC MI AOE.pptx
 
Emil Eifrem at GraphSummit Copenhagen 2024 - The Art of the Possible.pptx
Emil Eifrem at GraphSummit Copenhagen 2024 - The Art of the Possible.pptxEmil Eifrem at GraphSummit Copenhagen 2024 - The Art of the Possible.pptx
Emil Eifrem at GraphSummit Copenhagen 2024 - The Art of the Possible.pptx
 
The Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightThe Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and Insight
 
Q4 2023 Quarterly Investor Presentation - FINAL - v1.pdf
Q4 2023 Quarterly Investor Presentation - FINAL - v1.pdfQ4 2023 Quarterly Investor Presentation - FINAL - v1.pdf
Q4 2023 Quarterly Investor Presentation - FINAL - v1.pdf
 
Novo Nordisk's journey in developing an open-source application on Neo4j
Novo Nordisk's journey in developing an open-source application on Neo4jNovo Nordisk's journey in developing an open-source application on Neo4j
Novo Nordisk's journey in developing an open-source application on Neo4j
 
AI Workshops at Computers In Libraries 2024
AI Workshops at Computers In Libraries 2024AI Workshops at Computers In Libraries 2024
AI Workshops at Computers In Libraries 2024
 
UiPath Studio Web workshop series - Day 2
UiPath Studio Web workshop series - Day 2UiPath Studio Web workshop series - Day 2
UiPath Studio Web workshop series - Day 2
 
How to release an Open Source Dataweave Library
How to release an Open Source Dataweave LibraryHow to release an Open Source Dataweave Library
How to release an Open Source Dataweave Library
 
Oracle Database 23c Security New Features.pptx
Oracle Database 23c Security New Features.pptxOracle Database 23c Security New Features.pptx
Oracle Database 23c Security New Features.pptx
 
Introduction - IPLOOK NETWORKS CO., LTD.
Introduction - IPLOOK NETWORKS CO., LTD.Introduction - IPLOOK NETWORKS CO., LTD.
Introduction - IPLOOK NETWORKS CO., LTD.
 
TrustArc Webinar - How to Live in a Post Third-Party Cookie World
TrustArc Webinar - How to Live in a Post Third-Party Cookie WorldTrustArc Webinar - How to Live in a Post Third-Party Cookie World
TrustArc Webinar - How to Live in a Post Third-Party Cookie World
 

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