SlideShare ist ein Scribd-Unternehmen logo
1 von 74
Downloaden Sie, um offline zu lesen
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

Weitere ähnliche Inhalte

Was ist angesagt?

Ad hoc Polymorphism using Type Classes and Cats
Ad hoc Polymorphism using Type Classes and CatsAd hoc Polymorphism using Type Classes and Cats
Ad hoc Polymorphism using Type Classes and CatsPhilip Schwarz
 
ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022Alexander Ioffe
 
Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Scott Wlaschin
 
Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)Scott Wlaschin
 
Functor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadOliver Daff
 
Pipeline oriented programming
Pipeline oriented programmingPipeline oriented programming
Pipeline oriented programmingScott Wlaschin
 
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
 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...Philip Schwarz
 
Introduction to Go programming language
Introduction to Go programming languageIntroduction to Go programming language
Introduction to Go programming languageSlawomir Dorzak
 
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
 
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
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Chris Richardson
 
The Power of Composition (NDC Oslo 2020)
The Power of Composition (NDC Oslo 2020)The Power of Composition (NDC Oslo 2020)
The Power of Composition (NDC Oslo 2020)Scott Wlaschin
 
Using Redux-Saga for Handling Side Effects
Using Redux-Saga for Handling Side EffectsUsing Redux-Saga for Handling Side Effects
Using Redux-Saga for Handling Side EffectsGlobalLogic Ukraine
 
Clean architecture with ddd layering in php
Clean architecture with ddd layering in phpClean architecture with ddd layering in php
Clean architecture with ddd layering in phpLeonardo Proietti
 
Developing for Node.JS with MySQL and NoSQL
Developing for Node.JS with MySQL and NoSQLDeveloping for Node.JS with MySQL and NoSQL
Developing for Node.JS with MySQL and NoSQLJohn David Duncan
 

Was ist angesagt? (20)

Ad hoc Polymorphism using Type Classes and Cats
Ad hoc Polymorphism using Type Classes and CatsAd hoc Polymorphism using Type Classes and Cats
Ad hoc Polymorphism using Type Classes and Cats
 
ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022
 
Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)
 
Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)
 
Functor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And Monad
 
Pipeline oriented programming
Pipeline oriented programmingPipeline oriented programming
Pipeline oriented 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
 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
 
Introduction to Go programming language
Introduction to Go programming languageIntroduction to Go programming language
Introduction to Go programming language
 
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
 
Google Maps JS API
Google Maps JS APIGoogle Maps JS API
Google Maps JS API
 
Callback Function
Callback FunctionCallback Function
Callback Function
 
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
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
 
The Power of Composition (NDC Oslo 2020)
The Power of Composition (NDC Oslo 2020)The Power of Composition (NDC Oslo 2020)
The Power of Composition (NDC Oslo 2020)
 
Applicative style programming
Applicative style programmingApplicative style programming
Applicative style programming
 
Java 8 Lambda and Streams
Java 8 Lambda and StreamsJava 8 Lambda and Streams
Java 8 Lambda and Streams
 
Using Redux-Saga for Handling Side Effects
Using Redux-Saga for Handling Side EffectsUsing Redux-Saga for Handling Side Effects
Using Redux-Saga for Handling Side Effects
 
Clean architecture with ddd layering in php
Clean architecture with ddd layering in phpClean architecture with ddd layering in php
Clean architecture with ddd layering in php
 
Developing for Node.JS with MySQL and NoSQL
Developing for Node.JS with MySQL and NoSQLDeveloping for Node.JS with MySQL and NoSQL
Developing for Node.JS with MySQL and NoSQL
 

Ähnlich wie 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
 
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
 
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
 

Ähnlich wie 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
 
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
 
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
 

Mehr von 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
 
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
 

Mehr von 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
 
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
 

Kürzlich hochgeladen

TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
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
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
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
 
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
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
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
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
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
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
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
 
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
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
"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 Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 

Kürzlich hochgeladen (20)

TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
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
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
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
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
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
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
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
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
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
 
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
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
"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 Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.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