SlideShare uma empresa Scribd logo
1 de 25
Monads and friends
demystified
About me
Blog: http://www.alessandrolacava.com
GitHub: https://github.com/lambdista
Twitter: https://twitter.com/lambdista
LinkedIn: https://www.linkedin.com/in/alessandrolacava
Type Classes 101
// 1. Capture a concept
trait Show[A] {
def show(a: A): String
}
object Show {
// 2. Define a method that accept, implicitly, an instance of the concept
def show[A](a: A)(implicit ev: Show[A]): String = ev.show(a)
}
// 3. Implement some instances of the concept
implicit val intShow = new Show[Int] {
override def show(a: Int): String = a.toString
}
Type Classes 102
object Show {
// Alternative syntax
def show[A: Show](a: A): String = implicitly[Show[A]].show(a)
}
Type Classes 103
object Show {
// Commonly used pattern
def apply[A: Show] = implicitly[Show[A]]
// All methods using Show can now use this syntax
def show[A: Show](a: A): String = Show[A].show(a)
}
Higher-kinded types
Kinds in Type Theory
Symbol Kind Examples
* Simple type. AKA nullary
type constructor or proper
type.
Int, String, Double, ...
* -> * Unary type constructor. List, Option, Set, ...
* -> * -> * Binary type constructor. Either, Function1, Map, ...
(* -> *) -> * Higher-order type operator,
higher-kinded type for
friends.
Foo[F[_]], Bar[G[_]],
Functor[F[_]], Monad[M[_]],
...
Example: Mappable
Capturing the concept represented by the map method (See: Option, …):
trait Mappable[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
object Mappable {
def apply[F[_]: Mappable]: Mappable[F] = implicitly[Mappable[F]]
def map[F[_]: Mappable, A, B](ma: F[A])(f: A => B): F[B] = Mappable[F].map(ma)(f)
implicit val optionMapper = new Mappaple[Option] {
override def map[A, B](oa: Option[A])(f: A => B): Option[B] = oa.map(f)
}
implicit val listMapper = new Mappaple[List] {
override def map[A, B](la: List[A])(f: A => B): List[B] = la.map(f)
}
}
Functor: Change the Mappable name...
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
object Functor {
def apply[F[_]: Functor]: Functor[F] = implicitly[Functor[F]]
def map[F[_]: Functor, A, B](ma: F[A])(f: A => B): F[B] = Functor[F].map(ma)(f)
implicit val optionFunctor = new Functor[Option] {
override def map[A, B](oa: Option[A])(f: A => B): Option[B] = oa.map(f)
}
implicit val listFunctor = new Functor[List] {
override def map[A, B](la: List[A])(f: A => B): List[B] = la.map(f)
}
}
...and add a couple of laws
In order for something to be a functor, it should satisfy a couple of laws:
Given a functor fa: F[A] and the identity function defined as follows:
def identity[A](a: A): A = a
the following laws must hold (where the order of the args is swapped, the Haskell way):
Identity Law: map(identity)(fa) = fa
Composition Law: map(f compose g)(fa) = map(f)(map(g)(fa))
Identity Law
map(identity)(fa) = fa => map(identity) = identity
E.g.: Option[A]
import Functor._
val some: Option[Int] = Some(42)
val none: Option[Int] = None
assert(map(some)(identity) == some)
assert(map(none)(identity) == none)
Composition Law
map(f compose g)(fa) = map(f)(map(g)(fa))
E.g.: Option[A]
val f: Int => Int = x => x + 42
val g: Int => Int = x => x * x
assert(map(some)(f compose g) == map(map(some)(g))(f))
assert(map(none)(f compose g) == map(map(none)(g))(f))
Note: The compiler cannot enforce these laws. You need to ensure them yourself.
Lessons Learned
The Mappable concept was
easier to get because the
name didn’t scare you.
Rule I: Don’t let the
buzzwords scare you
Everything gets easier if you
look closely at the types.
Rule II: Always follow the
types.
Case Study
A Functor lets us apply a function to a value which is inside a context. Context
examples: Option, List, Future.
Now, what if the function you want to apply is within a context as well?
E.g.:
def interpret(str: String): Option[Int => Int] = str.toLowerCase match {
case "incr" => Some(_ + 1)
case "decr" => Some(_ - 1)
case "square" => Some(x => x * x)
case "halve" => Some(x => x / 2)
case _ => None
}
val v: Option[Int] = Some(42)
Enter The Applicative Functor
Capturing the concept of a function within a context, that is F[A => B]:
trait Applicative[F[_]] extends Functor[F] {
def pure[A](a: A): F[A]
def ap[A, B](fa: F[A])(fab: F[A => B]): F[B]
// from applicative you get a functor for free
override def map[A, B](fa: F[A])(fab: A => B): F[B] =
}
object Applicative {
def apply[F[_]: Applicative]: Applicative[F] = implicitly[Applicative[F]]
def pure[F[_]: Applicative, A](a: A): F[A] = Applicative[F].pure(a)
def ap[F[_]: Applicative, A, B](fa: F[A])(fab: F[A => B]): F[B] =
Applicative[F].ap(fa)(fab)
// ... Applicative instances
}
ap(fa)(pure(fab))
Applicative instances
object Applicative {
// ...
implicit val optionApplicative = new Applicative[Option] {
override def pure[A](a: A): Option[A] = Option(a)
override def ap[A, B](fa: Option[A])(fab: Option[A => B]): Option[B] = for {
a <- fa
f <- fab
} yield f(a)
}
implicit val listApplicative = new Applicative[List] {
override def pure[A](a: A): List[A] = List(a)
override def ap[A, B](fa: List[A])(fab: List[A => B]): List[B] = for {
a <- fa
f <- fab
} yield f(a)
}
}
The Applicative Functor needs some laws satisfied as well that we won’t cover here.
Case Study Solved
import Applicative._
def interpret(str: String): Option[Int => Int] = str.toLowerCase match {
case "incr" => Some(_ + 1)
case "decr" => Some(_ - 1)
case "square" => Some(x => x * x)
case "halve" => Some(x => x / 2)
case _ => None
}
val func: Option[Int => Int] = interpret("incr")
val v: Option[Int] = Some(42)
val result: Option[Int] = ap(v)(func)
And now the dreadful Monad
If C is a Category a monad on C consists of an endofunctor T: C -> C together
with two natural transformations:
η: 1C -> T (where 1C denotes the identity functor on C)
μ: T2 -> T (where T2 is the functor T T from C to C).
These are required to fulfill the following conditions (sometimes called coherence
conditions):
μ Tμ = μ μ T (as natural transformations T3 -> T);
μ T η = μ η T = 1T (as natural transformations T -> T; here 1T denotes the
identity transformation from T to T).
Just Kidding!
Well, not really. That’s the Wikipedia definition
Monad for developers
trait Monad[M[_]] extends Applicative[M] {
def unit[A](a: A): M[A]
def flatMap[A, B](ma: M[A])(f: A => M[B]): M[B]
override def pure[A](a: A): M[A] = unit(a)
override def ap[A, B](fa: M[A])(f: M[A => B]): M[B] =
flatMap(fa)(a => map(f)(ff => ff(a)))
}
The primitives required by the Monad type class are just unit and flatMap or, equivalently, unit and join (along with map
inherited from Functor):
def join(mma: M[M[A]]): M[A]
You can derive flatMap from unit, join and map.
Monad continued...
object Monad {
def apply[M[_] : Monad]: Monad[M] = implicitly[Monad[M]]
def unit[M[_]: Monad, A](a: A): M[A] = Monad[M].unit(a)
def flatMap[M[_]: Monad, A, B](ma: M[A])(f: A => M[B]): M[B] = Monad[M].flatMap(ma)(f)
implicit val optionMonad = new Monad[Option] {
override def unit[A](a: A): Option[A] = Option(a)
override def flatMap[A, B](ma: Option[A])(f: A => Option[B]): Option[B] =
ma.flatMap(f)
}
implicit val listMonad = new Monad[List] {
override def unit[A](a: A): List[A] = List(a)
override def flatMap[A, B](ma: List[A])(f: A => List[B]): List[B] = ma.flatMap(f)
}
}
Monad Laws
Do we need to write our own type classes and implementations for concepts such as Functor, Applicative and Monad?
In Scala pseudocode:
Left Identity: unit(a).flatMap(f) == f(a)
Right Identity: m.flatMap(unit) == m
Associativity: (m.flatMap(f)).flatMap(g) == m.flatMap(a => f(a).flatMap(g))
Not really!
Cats
GitHub: https://github.com/typelevel/cats
libraryDependencies += "org.typelevel" %% "cats" % catsVersion
Resources for Learners:
http://typelevel.org/cats/
http://eed3si9n.com/herding-cats/
Cats is broken up into a number of sub-projects:
● core - contains type class definitions (e.g. Functor, Applicative, Monad), essential datatypes, and
type class instances for those datatypes and standard library types
● laws - laws for the type classes, used to validate type class instances
● tests - tests that check type class instances with laws from laws
● docs - The source for this website
Cats (0.4.0): Example
import cats._
import cats.std.all._
val inc: Int => Int = _ + 1
val some: Option[Int] = Some(42)
val none: Option[Int] = None
val list: List[Int] = List(1, 2, 3)
val emptyList: List[Int] = List()
val optResult1 = Functor[Option].map(some)(inc) // Some(43)
val optResult2 = Functor[Option].map(none)(inc) // None
val listResult1 = Functor[List].map(list)(inc) // List(2, 3, 4)
val listResult2 = Functor[List].map(emptyList)(inc) // List()
Nice. But it would be more useful if we could abstract over Functor, wouldn’t it?
Cats (0.4.0): Abstracting over Functor
val inc: Int => Int = _ + 1
val some: Option[Int] = Some(42)
val none: Option[Int] = None
val list: List[Int] = List(1, 2, 3)
val emptyList: List[Int] = List()
def map[F[_]: Functor, A, B](fa: F[A])(f: A => B): F[B] = Functor[F].map(fa)(f)
val optResult3 = map(some)(inc) // Some(43)
val listResult3 = map(list)(inc) // List(2, 3, 4)
Great. Now what if we want to compose two functors? No problem man!
Cats (0.4.0): Functors compose!
val inc: Int => Int = _ + 1
val listOfOpts = List(Some(1), None, Some(3))
// We want to map inc to listOfOpts
val listOptFunctor = Functor[List] compose Functor[Option]
val listOptResult = listOptFunctor.map(listOfOpts)(inc) // List(Some(2), None, Some(4))
Applicatives compose too. Monads do not, mechanically, compose. Some of them do and their
composition is generally achieved through Monad transformers.
Shameless Plug
I dealt with these and other subjects in this book: Professional Scala - Wrox
URL: http://eu.wiley.com/WileyCDA/WileyTitle/productCd-1119267226.html

Mais conteúdo relacionado

Mais procurados

Why functional programming and category theory strongly matters
Why functional programming and category theory strongly mattersWhy functional programming and category theory strongly matters
Why functional programming and category theory strongly mattersPiotr Paradziński
 
Principled Error Handling with FP
Principled Error Handling with FPPrincipled Error Handling with FP
Principled Error Handling with FPLuka Jacobowitz
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2Hang Zhao
 
Effective way to code in Scala
Effective way to code in ScalaEffective way to code in Scala
Effective way to code in ScalaKnoldus Inc.
 
Functor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadOliver Daff
 
Type Parameterization
Type ParameterizationType Parameterization
Type ParameterizationKnoldus Inc.
 
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
 
First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class PatternsJohn De Goes
 
Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Philip Schwarz
 
Monad Transformers - Part 1
Monad Transformers - Part 1Monad Transformers - Part 1
Monad Transformers - Part 1Philip Schwarz
 
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
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala Knoldus Inc.
 
Traversals for all ocasions
Traversals for all ocasionsTraversals for all ocasions
Traversals for all ocasionsLuka Jacobowitz
 
The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final TaglessJohn 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
 
Contravariant functors in scala
Contravariant functors in scalaContravariant functors in scala
Contravariant functors in scalaPiotr Paradziński
 

Mais procurados (19)

Why functional programming and category theory strongly matters
Why functional programming and category theory strongly mattersWhy functional programming and category theory strongly matters
Why functional programming and category theory strongly matters
 
Principled Error Handling with FP
Principled Error Handling with FPPrincipled Error Handling with FP
Principled Error Handling with FP
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
 
Effective way to code in Scala
Effective way to code in ScalaEffective way to code in Scala
Effective way to code in Scala
 
Functor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And Monad
 
Type Parameterization
Type ParameterizationType Parameterization
Type Parameterization
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New Game
 
First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class Patterns
 
Functors
FunctorsFunctors
Functors
 
Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3
 
Monad Transformers - Part 1
Monad Transformers - Part 1Monad Transformers - Part 1
Monad Transformers - Part 1
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them All
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala
 
Traversals for all ocasions
Traversals for all ocasionsTraversals for all ocasions
Traversals for all ocasions
 
The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final Tagless
 
Lambdaconf2019 talk
Lambdaconf2019 talkLambdaconf2019 talk
Lambdaconf2019 talk
 
09. haskell Context
09. haskell Context09. haskell Context
09. haskell Context
 
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
 
Contravariant functors in scala
Contravariant functors in scalaContravariant functors in scala
Contravariant functors in scala
 

Destaque

V. Rapševičius. Navigacija uždarose patalpose - misija įmanoma. GIS - paprast...
V. Rapševičius. Navigacija uždarose patalpose - misija įmanoma. GIS - paprast...V. Rapševičius. Navigacija uždarose patalpose - misija įmanoma. GIS - paprast...
V. Rapševičius. Navigacija uždarose patalpose - misija įmanoma. GIS - paprast...opengislt
 
Stephen Mounsey - Performance Testing it's not that scary
Stephen Mounsey - Performance Testing it's not that scaryStephen Mounsey - Performance Testing it's not that scary
Stephen Mounsey - Performance Testing it's not that scaryAgile Lietuva
 
Present Connection 1 year review
Present Connection 1 year reviewPresent Connection 1 year review
Present Connection 1 year reviewDomantas Jovaisas
 
Priit Kaasik and Heldin Rikk - It’s Like Continuous Improvement, Only Better
Priit Kaasik and Heldin Rikk - It’s Like Continuous Improvement, Only BetterPriit Kaasik and Heldin Rikk - It’s Like Continuous Improvement, Only Better
Priit Kaasik and Heldin Rikk - It’s Like Continuous Improvement, Only BetterAgile Lietuva
 
S. Kaukėnas. Kelių ženklinimo klaidų aptikimas žemėlapiuose. GIS - paprasta i...
S. Kaukėnas. Kelių ženklinimo klaidų aptikimas žemėlapiuose. GIS - paprasta i...S. Kaukėnas. Kelių ženklinimo klaidų aptikimas žemėlapiuose. GIS - paprasta i...
S. Kaukėnas. Kelių ženklinimo klaidų aptikimas žemėlapiuose. GIS - paprasta i...opengislt
 
Campamento Noviembre 2008
Campamento Noviembre 2008Campamento Noviembre 2008
Campamento Noviembre 2008jorgefilu
 
Karolis Volodkovičius - Kai visas pasaulis prieš tave
Karolis Volodkovičius - Kai visas pasaulis prieš  taveKarolis Volodkovičius - Kai visas pasaulis prieš  tave
Karolis Volodkovičius - Kai visas pasaulis prieš taveAgile Lietuva
 
Advance Scala - Oleg Mürk
Advance Scala - Oleg MürkAdvance Scala - Oleg Mürk
Advance Scala - Oleg MürkPlanet OS
 
Les Tic A La Fundació Llor
Les Tic A La Fundació LlorLes Tic A La Fundació Llor
Les Tic A La Fundació Llorsilvimarco
 
V. Nareiko. Internetinis žemėlapis nemasinis.lt. GIS - paprasta ir atvira 2015.
V. Nareiko. Internetinis žemėlapis nemasinis.lt. GIS - paprasta ir atvira 2015.V. Nareiko. Internetinis žemėlapis nemasinis.lt. GIS - paprasta ir atvira 2015.
V. Nareiko. Internetinis žemėlapis nemasinis.lt. GIS - paprasta ir atvira 2015.opengislt
 
Titas Lapinskas - Technical Team Leader in Agile
Titas Lapinskas - Technical Team Leader in AgileTitas Lapinskas - Technical Team Leader in Agile
Titas Lapinskas - Technical Team Leader in AgileAgile Lietuva
 
Trūksta pinigų ar negali rasti darbo?
Trūksta pinigų ar negali rasti darbo?Trūksta pinigų ar negali rasti darbo?
Trūksta pinigų ar negali rasti darbo?LingJob
 
Lemi Orhan Ergin - Code Your Agility: Tips for Boosting Technical Agility in ...
Lemi Orhan Ergin - Code Your Agility: Tips for Boosting Technical Agility in ...Lemi Orhan Ergin - Code Your Agility: Tips for Boosting Technical Agility in ...
Lemi Orhan Ergin - Code Your Agility: Tips for Boosting Technical Agility in ...Agile Lietuva
 

Destaque (20)

V. Rapševičius. Navigacija uždarose patalpose - misija įmanoma. GIS - paprast...
V. Rapševičius. Navigacija uždarose patalpose - misija įmanoma. GIS - paprast...V. Rapševičius. Navigacija uždarose patalpose - misija įmanoma. GIS - paprast...
V. Rapševičius. Navigacija uždarose patalpose - misija įmanoma. GIS - paprast...
 
Stephen Mounsey - Performance Testing it's not that scary
Stephen Mounsey - Performance Testing it's not that scaryStephen Mounsey - Performance Testing it's not that scary
Stephen Mounsey - Performance Testing it's not that scary
 
Cmsms
CmsmsCmsms
Cmsms
 
Present Connection 1 year review
Present Connection 1 year reviewPresent Connection 1 year review
Present Connection 1 year review
 
Priit Kaasik and Heldin Rikk - It’s Like Continuous Improvement, Only Better
Priit Kaasik and Heldin Rikk - It’s Like Continuous Improvement, Only BetterPriit Kaasik and Heldin Rikk - It’s Like Continuous Improvement, Only Better
Priit Kaasik and Heldin Rikk - It’s Like Continuous Improvement, Only Better
 
S. Kaukėnas. Kelių ženklinimo klaidų aptikimas žemėlapiuose. GIS - paprasta i...
S. Kaukėnas. Kelių ženklinimo klaidų aptikimas žemėlapiuose. GIS - paprasta i...S. Kaukėnas. Kelių ženklinimo klaidų aptikimas žemėlapiuose. GIS - paprasta i...
S. Kaukėnas. Kelių ženklinimo klaidų aptikimas žemėlapiuose. GIS - paprasta i...
 
Campamento Noviembre 2008
Campamento Noviembre 2008Campamento Noviembre 2008
Campamento Noviembre 2008
 
Karolis Volodkovičius - Kai visas pasaulis prieš tave
Karolis Volodkovičius - Kai visas pasaulis prieš  taveKarolis Volodkovičius - Kai visas pasaulis prieš  tave
Karolis Volodkovičius - Kai visas pasaulis prieš tave
 
Sm 10 6 09
Sm 10 6 09Sm 10 6 09
Sm 10 6 09
 
Cosas antiguas
Cosas antiguasCosas antiguas
Cosas antiguas
 
Advance Scala - Oleg Mürk
Advance Scala - Oleg MürkAdvance Scala - Oleg Mürk
Advance Scala - Oleg Mürk
 
Les Tic A La Fundació Llor
Les Tic A La Fundació LlorLes Tic A La Fundació Llor
Les Tic A La Fundació Llor
 
V. Nareiko. Internetinis žemėlapis nemasinis.lt. GIS - paprasta ir atvira 2015.
V. Nareiko. Internetinis žemėlapis nemasinis.lt. GIS - paprasta ir atvira 2015.V. Nareiko. Internetinis žemėlapis nemasinis.lt. GIS - paprasta ir atvira 2015.
V. Nareiko. Internetinis žemėlapis nemasinis.lt. GIS - paprasta ir atvira 2015.
 
Titas Lapinskas - Technical Team Leader in Agile
Titas Lapinskas - Technical Team Leader in AgileTitas Lapinskas - Technical Team Leader in Agile
Titas Lapinskas - Technical Team Leader in Agile
 
Pucc practical notes_i
Pucc practical notes_iPucc practical notes_i
Pucc practical notes_i
 
Strategic issues on WHO agenda
Strategic issues on WHO agendaStrategic issues on WHO agenda
Strategic issues on WHO agenda
 
YOGA FOR MUSCULOSKELETAL DISORDERS
YOGA FOR MUSCULOSKELETAL DISORDERSYOGA FOR MUSCULOSKELETAL DISORDERS
YOGA FOR MUSCULOSKELETAL DISORDERS
 
Asp_4_Presentation
Asp_4_PresentationAsp_4_Presentation
Asp_4_Presentation
 
Trūksta pinigų ar negali rasti darbo?
Trūksta pinigų ar negali rasti darbo?Trūksta pinigų ar negali rasti darbo?
Trūksta pinigų ar negali rasti darbo?
 
Lemi Orhan Ergin - Code Your Agility: Tips for Boosting Technical Agility in ...
Lemi Orhan Ergin - Code Your Agility: Tips for Boosting Technical Agility in ...Lemi Orhan Ergin - Code Your Agility: Tips for Boosting Technical Agility in ...
Lemi Orhan Ergin - Code Your Agility: Tips for Boosting Technical Agility in ...
 

Semelhante a Monads and friends demystified

The Essence of the Iterator Pattern
The Essence of the Iterator PatternThe Essence of the Iterator Pattern
The Essence of the Iterator PatternEric Torreborre
 
The Essence of the Iterator Pattern (pdf)
The Essence of the Iterator Pattern (pdf)The Essence of the Iterator Pattern (pdf)
The Essence of the Iterator Pattern (pdf)Eric Torreborre
 
(2015 06-16) Three Approaches to Monads
(2015 06-16) Three Approaches to Monads(2015 06-16) Three Approaches to Monads
(2015 06-16) Three Approaches to MonadsLawrence Evans
 
Scala collection methods flatMap and flatten are more powerful than monadic f...
Scala collection methods flatMap and flatten are more powerful than monadic f...Scala collection methods flatMap and flatten are more powerful than monadic f...
Scala collection methods flatMap and flatten are more powerful than monadic f...Philip Schwarz
 
Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Embedding Generic Monadic Transformer into Scala. [Tfp2022]Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Embedding Generic Monadic Transformer into Scala. [Tfp2022]Ruslan Shevchenko
 
Monads - Dublin Scala meetup
Monads - Dublin Scala meetupMonads - Dublin Scala meetup
Monads - Dublin Scala meetupMikhail Girkin
 
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
 
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...Scalac
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and EffectsRaymond Roestenburg
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patternsleague
 
Делаем пользовательское Api на базе Shapeless
Делаем пользовательское Api на базе ShapelessДелаем пользовательское Api на базе Shapeless
Делаем пользовательское Api на базе ShapelessВадим Челышов
 
Generic Functional Programming with Type Classes
Generic Functional Programming with Type ClassesGeneric Functional Programming with Type Classes
Generic Functional Programming with Type ClassesTapio Rautonen
 
From Functor Composition to Monad Transformers
From Functor Composition to Monad TransformersFrom Functor Composition to Monad Transformers
From Functor Composition to Monad TransformersHermann Hueck
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systemsleague
 

Semelhante a Monads and friends demystified (20)

The Essence of the Iterator Pattern
The Essence of the Iterator PatternThe Essence of the Iterator Pattern
The Essence of the Iterator Pattern
 
The Essence of the Iterator Pattern (pdf)
The Essence of the Iterator Pattern (pdf)The Essence of the Iterator Pattern (pdf)
The Essence of the Iterator Pattern (pdf)
 
(2015 06-16) Three Approaches to Monads
(2015 06-16) Three Approaches to Monads(2015 06-16) Three Approaches to Monads
(2015 06-16) Three Approaches to Monads
 
Scala collection methods flatMap and flatten are more powerful than monadic f...
Scala collection methods flatMap and flatten are more powerful than monadic f...Scala collection methods flatMap and flatten are more powerful than monadic f...
Scala collection methods flatMap and flatten are more powerful than monadic f...
 
Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Embedding Generic Monadic Transformer into Scala. [Tfp2022]Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Embedding Generic Monadic Transformer into Scala. [Tfp2022]
 
Monads - Dublin Scala meetup
Monads - Dublin Scala meetupMonads - Dublin Scala meetup
Monads - Dublin Scala meetup
 
Thesis
ThesisThesis
Thesis
 
Thesis PPT
Thesis PPTThesis PPT
Thesis PPT
 
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...
 
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...
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and Effects
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
 
Practical cats
Practical catsPractical cats
Practical cats
 
Monads do not Compose
Monads do not ComposeMonads do not Compose
Monads do not Compose
 
Делаем пользовательское Api на базе Shapeless
Делаем пользовательское Api на базе ShapelessДелаем пользовательское Api на базе Shapeless
Делаем пользовательское Api на базе Shapeless
 
Generic Functional Programming with Type Classes
Generic Functional Programming with Type ClassesGeneric Functional Programming with Type Classes
Generic Functional Programming with Type Classes
 
From Functor Composition to Monad Transformers
From Functor Composition to Monad TransformersFrom Functor Composition to Monad Transformers
From Functor Composition to Monad Transformers
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systems
 
Monad Fact #4
Monad Fact #4Monad Fact #4
Monad Fact #4
 
From OOP To FP Through A Practical Case
From OOP To FP Through A Practical CaseFrom OOP To FP Through A Practical Case
From OOP To FP Through A Practical Case
 

Último

call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...masabamasaba
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is insideshinachiaurasa2
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfproinshot.com
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastPapp Krisztián
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...masabamasaba
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...SelfMade bd
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdfPearlKirahMaeRagusta1
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...masabamasaba
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024Mind IT Systems
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...masabamasaba
 

Último (20)

call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 

Monads and friends demystified

  • 2. About me Blog: http://www.alessandrolacava.com GitHub: https://github.com/lambdista Twitter: https://twitter.com/lambdista LinkedIn: https://www.linkedin.com/in/alessandrolacava
  • 3. Type Classes 101 // 1. Capture a concept trait Show[A] { def show(a: A): String } object Show { // 2. Define a method that accept, implicitly, an instance of the concept def show[A](a: A)(implicit ev: Show[A]): String = ev.show(a) } // 3. Implement some instances of the concept implicit val intShow = new Show[Int] { override def show(a: Int): String = a.toString }
  • 4. Type Classes 102 object Show { // Alternative syntax def show[A: Show](a: A): String = implicitly[Show[A]].show(a) }
  • 5. Type Classes 103 object Show { // Commonly used pattern def apply[A: Show] = implicitly[Show[A]] // All methods using Show can now use this syntax def show[A: Show](a: A): String = Show[A].show(a) }
  • 6. Higher-kinded types Kinds in Type Theory Symbol Kind Examples * Simple type. AKA nullary type constructor or proper type. Int, String, Double, ... * -> * Unary type constructor. List, Option, Set, ... * -> * -> * Binary type constructor. Either, Function1, Map, ... (* -> *) -> * Higher-order type operator, higher-kinded type for friends. Foo[F[_]], Bar[G[_]], Functor[F[_]], Monad[M[_]], ...
  • 7. Example: Mappable Capturing the concept represented by the map method (See: Option, …): trait Mappable[F[_]] { def map[A, B](fa: F[A])(f: A => B): F[B] } object Mappable { def apply[F[_]: Mappable]: Mappable[F] = implicitly[Mappable[F]] def map[F[_]: Mappable, A, B](ma: F[A])(f: A => B): F[B] = Mappable[F].map(ma)(f) implicit val optionMapper = new Mappaple[Option] { override def map[A, B](oa: Option[A])(f: A => B): Option[B] = oa.map(f) } implicit val listMapper = new Mappaple[List] { override def map[A, B](la: List[A])(f: A => B): List[B] = la.map(f) } }
  • 8. Functor: Change the Mappable name... trait Functor[F[_]] { def map[A, B](fa: F[A])(f: A => B): F[B] } object Functor { def apply[F[_]: Functor]: Functor[F] = implicitly[Functor[F]] def map[F[_]: Functor, A, B](ma: F[A])(f: A => B): F[B] = Functor[F].map(ma)(f) implicit val optionFunctor = new Functor[Option] { override def map[A, B](oa: Option[A])(f: A => B): Option[B] = oa.map(f) } implicit val listFunctor = new Functor[List] { override def map[A, B](la: List[A])(f: A => B): List[B] = la.map(f) } }
  • 9. ...and add a couple of laws In order for something to be a functor, it should satisfy a couple of laws: Given a functor fa: F[A] and the identity function defined as follows: def identity[A](a: A): A = a the following laws must hold (where the order of the args is swapped, the Haskell way): Identity Law: map(identity)(fa) = fa Composition Law: map(f compose g)(fa) = map(f)(map(g)(fa))
  • 10. Identity Law map(identity)(fa) = fa => map(identity) = identity E.g.: Option[A] import Functor._ val some: Option[Int] = Some(42) val none: Option[Int] = None assert(map(some)(identity) == some) assert(map(none)(identity) == none)
  • 11. Composition Law map(f compose g)(fa) = map(f)(map(g)(fa)) E.g.: Option[A] val f: Int => Int = x => x + 42 val g: Int => Int = x => x * x assert(map(some)(f compose g) == map(map(some)(g))(f)) assert(map(none)(f compose g) == map(map(none)(g))(f)) Note: The compiler cannot enforce these laws. You need to ensure them yourself.
  • 12. Lessons Learned The Mappable concept was easier to get because the name didn’t scare you. Rule I: Don’t let the buzzwords scare you Everything gets easier if you look closely at the types. Rule II: Always follow the types.
  • 13. Case Study A Functor lets us apply a function to a value which is inside a context. Context examples: Option, List, Future. Now, what if the function you want to apply is within a context as well? E.g.: def interpret(str: String): Option[Int => Int] = str.toLowerCase match { case "incr" => Some(_ + 1) case "decr" => Some(_ - 1) case "square" => Some(x => x * x) case "halve" => Some(x => x / 2) case _ => None } val v: Option[Int] = Some(42)
  • 14. Enter The Applicative Functor Capturing the concept of a function within a context, that is F[A => B]: trait Applicative[F[_]] extends Functor[F] { def pure[A](a: A): F[A] def ap[A, B](fa: F[A])(fab: F[A => B]): F[B] // from applicative you get a functor for free override def map[A, B](fa: F[A])(fab: A => B): F[B] = } object Applicative { def apply[F[_]: Applicative]: Applicative[F] = implicitly[Applicative[F]] def pure[F[_]: Applicative, A](a: A): F[A] = Applicative[F].pure(a) def ap[F[_]: Applicative, A, B](fa: F[A])(fab: F[A => B]): F[B] = Applicative[F].ap(fa)(fab) // ... Applicative instances } ap(fa)(pure(fab))
  • 15. Applicative instances object Applicative { // ... implicit val optionApplicative = new Applicative[Option] { override def pure[A](a: A): Option[A] = Option(a) override def ap[A, B](fa: Option[A])(fab: Option[A => B]): Option[B] = for { a <- fa f <- fab } yield f(a) } implicit val listApplicative = new Applicative[List] { override def pure[A](a: A): List[A] = List(a) override def ap[A, B](fa: List[A])(fab: List[A => B]): List[B] = for { a <- fa f <- fab } yield f(a) } } The Applicative Functor needs some laws satisfied as well that we won’t cover here.
  • 16. Case Study Solved import Applicative._ def interpret(str: String): Option[Int => Int] = str.toLowerCase match { case "incr" => Some(_ + 1) case "decr" => Some(_ - 1) case "square" => Some(x => x * x) case "halve" => Some(x => x / 2) case _ => None } val func: Option[Int => Int] = interpret("incr") val v: Option[Int] = Some(42) val result: Option[Int] = ap(v)(func)
  • 17. And now the dreadful Monad If C is a Category a monad on C consists of an endofunctor T: C -> C together with two natural transformations: η: 1C -> T (where 1C denotes the identity functor on C) μ: T2 -> T (where T2 is the functor T T from C to C). These are required to fulfill the following conditions (sometimes called coherence conditions): μ Tμ = μ μ T (as natural transformations T3 -> T); μ T η = μ η T = 1T (as natural transformations T -> T; here 1T denotes the identity transformation from T to T). Just Kidding! Well, not really. That’s the Wikipedia definition
  • 18. Monad for developers trait Monad[M[_]] extends Applicative[M] { def unit[A](a: A): M[A] def flatMap[A, B](ma: M[A])(f: A => M[B]): M[B] override def pure[A](a: A): M[A] = unit(a) override def ap[A, B](fa: M[A])(f: M[A => B]): M[B] = flatMap(fa)(a => map(f)(ff => ff(a))) } The primitives required by the Monad type class are just unit and flatMap or, equivalently, unit and join (along with map inherited from Functor): def join(mma: M[M[A]]): M[A] You can derive flatMap from unit, join and map.
  • 19. Monad continued... object Monad { def apply[M[_] : Monad]: Monad[M] = implicitly[Monad[M]] def unit[M[_]: Monad, A](a: A): M[A] = Monad[M].unit(a) def flatMap[M[_]: Monad, A, B](ma: M[A])(f: A => M[B]): M[B] = Monad[M].flatMap(ma)(f) implicit val optionMonad = new Monad[Option] { override def unit[A](a: A): Option[A] = Option(a) override def flatMap[A, B](ma: Option[A])(f: A => Option[B]): Option[B] = ma.flatMap(f) } implicit val listMonad = new Monad[List] { override def unit[A](a: A): List[A] = List(a) override def flatMap[A, B](ma: List[A])(f: A => List[B]): List[B] = ma.flatMap(f) } }
  • 20. Monad Laws Do we need to write our own type classes and implementations for concepts such as Functor, Applicative and Monad? In Scala pseudocode: Left Identity: unit(a).flatMap(f) == f(a) Right Identity: m.flatMap(unit) == m Associativity: (m.flatMap(f)).flatMap(g) == m.flatMap(a => f(a).flatMap(g)) Not really!
  • 21. Cats GitHub: https://github.com/typelevel/cats libraryDependencies += "org.typelevel" %% "cats" % catsVersion Resources for Learners: http://typelevel.org/cats/ http://eed3si9n.com/herding-cats/ Cats is broken up into a number of sub-projects: ● core - contains type class definitions (e.g. Functor, Applicative, Monad), essential datatypes, and type class instances for those datatypes and standard library types ● laws - laws for the type classes, used to validate type class instances ● tests - tests that check type class instances with laws from laws ● docs - The source for this website
  • 22. Cats (0.4.0): Example import cats._ import cats.std.all._ val inc: Int => Int = _ + 1 val some: Option[Int] = Some(42) val none: Option[Int] = None val list: List[Int] = List(1, 2, 3) val emptyList: List[Int] = List() val optResult1 = Functor[Option].map(some)(inc) // Some(43) val optResult2 = Functor[Option].map(none)(inc) // None val listResult1 = Functor[List].map(list)(inc) // List(2, 3, 4) val listResult2 = Functor[List].map(emptyList)(inc) // List() Nice. But it would be more useful if we could abstract over Functor, wouldn’t it?
  • 23. Cats (0.4.0): Abstracting over Functor val inc: Int => Int = _ + 1 val some: Option[Int] = Some(42) val none: Option[Int] = None val list: List[Int] = List(1, 2, 3) val emptyList: List[Int] = List() def map[F[_]: Functor, A, B](fa: F[A])(f: A => B): F[B] = Functor[F].map(fa)(f) val optResult3 = map(some)(inc) // Some(43) val listResult3 = map(list)(inc) // List(2, 3, 4) Great. Now what if we want to compose two functors? No problem man!
  • 24. Cats (0.4.0): Functors compose! val inc: Int => Int = _ + 1 val listOfOpts = List(Some(1), None, Some(3)) // We want to map inc to listOfOpts val listOptFunctor = Functor[List] compose Functor[Option] val listOptResult = listOptFunctor.map(listOfOpts)(inc) // List(Some(2), None, Some(4)) Applicatives compose too. Monads do not, mechanically, compose. Some of them do and their composition is generally achieved through Monad transformers.
  • 25. Shameless Plug I dealt with these and other subjects in this book: Professional Scala - Wrox URL: http://eu.wiley.com/WileyCDA/WileyTitle/productCd-1119267226.html