SlideShare uma empresa Scribd logo
1 de 8
Baixar para ler offline
MONAD FACT #1
Scala for comprehensions require a monad to be defined in terms of
unit, map and flatMap rather than simply in terms of unit and flatMap
@philip_schwarzslides by
https://www.slideshare.net/pjschwarz
sealed trait Option[+A]
case object None extends Option[Nothing]
case class Some[+A](get: A) extends Option[A]
trait Monad[F[_]] {
def flatMap[A,B](ma: F[A])(f: A => F[B]): F[B]
def unit[A](a: => A): F[A]
}
val optionMonad = new Monad[Option] {
def unit[A](a: => A): Option[A] = Some(a)
def flatMap[A, B](ma: Option[A])(f: A => Option[B]): Option[B] = {
ma match {
case Some(a) => f(a)
case None => None
}
}
}
One way to define a monad is with the following trait
@philip_schwarz
If we define a data structure, e.g. an Option
we can then create a monad instance for Option by providing implementations for unit and flatMap
def greeting(maybeGreeting: Option[String],
maybeName: Option[String],
maybeSurname: Option[String]): Option[String] =
optionMonad.flatMap(maybeGreeting) { greeting =>
optionMonad.flatMap(maybeName) { name =>
optionMonad.flatMap(maybeSurname) { surname =>
optionMonad.unit(s"$greeting $name $surname!")
}
}
}
assert(
greeting(maybeGreeting = Some("Hello"), maybeName = Some("Fred"), maybeSurname = Some("Smith"))
== Some("Hello Fred Smith!"))
assert(
greeting(maybeGreeting = Some("Hello"), maybeName = None, maybeSurname = Some("Smith"))
== None)
Here is an example of using the Option monad instance
We just saw how to define the Option monad by defining unit and
flatMap functions that operate on Option.
Another way of defining the Option monad is by adding map and
flatMap functions to Option.
@philip_schwarz
If we do that, then we can take advantage of a
great Scala feature that allows code that uses the
monad to be much easier to understand than
woud otherwise be the case. Here is how the
greeting example looks like using this feature.
sealed trait Option[+A] {
def map[B](f: A => B): Option[B] =
this match {
case None => None
case Some(a) => Some(f(a))
}
def flatMap[B](f: A => Option[B]): Option[B] =
this match {
case None => None
case Some(a) => f(a)
}
}
case object None extends Option[Nothing]
case class Some[+A](get: A) extends Option[A]
def greeting(maybeGreeting: Option[String],
maybeName: Option[String],
maybeSurname: Option[String]): Option[String] =
for {
greeting <- maybeGreeting
name <- maybeName
surname <- maybeSurname
} yield s"$greeting $name $surname!"
assert(greeting(maybeGreeting = Some("Hello"), maybeName = Some("Fred"), maybeSurname = Some("Smith"))
== Some("Hello Fred Smith!"))
assert(greeting(maybeGreeting = Some("Hello"), maybeName = None, maybeSurname = Some("Smith"))
== None)
The feature in question is the ability to write an easy-to-understand for comprehension,
whose syntactic sugar is translated by the Scala compiler into a harder-to-understand
desugared chain of calls to map and flatMap
maybeGreeting flatMap { greeting =>
maybeName flatMap { name =>
maybeSurname map { surname =>
s"$greeting $name $surname!"
}
}
}
for {
greeting <- maybeGreeting
name <- maybeName
surname <- maybeSurname
} yield s"$greeting $name $surname!” desugars to
So why is it that in the first approach we can simply define a monad in terms of unit and flatMap
whereas in the second approach we have to define a monad in terms of unit, map and flatMap?
def map[B](f: A => B): Option[B] =
def flatMap[B](f: A => Option[B]): Option[B] =
case class Some[+A](get: A) extends Option[A] // Some acts as unit function
def flatMap[A,B](ma: F[A])(f: A => F[B]): F[B]
def unit[A](a: => A): F[A]
On the first slide we defined a monad simply in terms of unit and flatMap.
Later on, in order to take advantage of for comprehensions, we redefined a monad in terms of unit, map and
flatMap. “We did not define a unit function!”, I hear you say. Well, although it is not called unit, we did define it:
it is called Some, because creating a ‘defined’ Option, e.g. one with a value of 5, is done by evaluating Some(5)
(to get hold of the ‘undefined’ Option we use None).
@philip_schwarz
The answer to that question is that is that in Scala there is no Monad trait that monads can implement and that the compiler is
aware of, so the compiler does not know what the unit function of a monad is because for one thing, the function can have an
arbitrary name. In this case the unit function is called Some, in the case of the Either monad it is called Right, in the case of the List
monad it is called List, etc.
If there were some convention by which the compiler could figure out what the unit function of a monad is, then rather than
desugaring a for comprehension as follows:
It could desugar it to something like this:
maybeGreeting flatMap { greeting =>
maybeName flatMap { name =>
maybeSurname map { surname =>
s"$greeting $name $surname!"
}
}
}
for {
greeting <- maybeGreeting
name <- maybeName
surname <- maybeSurname
} yield s"$greeting $name $surname!” desugars to
maybeGreeting flatMap { greeting =>
maybeName flatMap { name =>
maybeSurname flatMap { surname =>
monadInstance.unit(s"$greeting $name $surname!")
}
}
}
maybeGreeting flatMap { greeting =>
maybeName flatMap { name =>
maybeSurname flatMap { surname =>
Some(s"$greeting $name $surname!")
}
}
}
See the following for the list of all available slide decks in the MONAD FACT series
https://www.slideshare.net/pjschwarz/the-monad-fact-slide-deck-series

Mais conteúdo relacionado

Mais de Philip Schwarz

N-Queens Combinatorial Puzzle meets Cats
N-Queens Combinatorial Puzzle meets CatsN-Queens Combinatorial Puzzle meets Cats
N-Queens Combinatorial Puzzle meets Cats
Philip Schwarz
 

Mais de Philip Schwarz (20)

A sighting of traverse_ function in Practical FP in Scala
A sighting of traverse_ function in Practical FP in ScalaA sighting of traverse_ function in Practical FP in Scala
A sighting of traverse_ function in Practical FP in Scala
 
A sighting of traverseFilter and foldMap in Practical FP in Scala
A sighting of traverseFilter and foldMap in Practical FP in ScalaA sighting of traverseFilter and foldMap in Practical FP in Scala
A sighting of traverseFilter and foldMap in Practical FP in Scala
 
A sighting of sequence function in Practical FP in Scala
A sighting of sequence function in Practical FP in ScalaA sighting of sequence function in Practical FP in Scala
A sighting of sequence function in Practical FP in Scala
 
N-Queens Combinatorial Puzzle meets Cats
N-Queens Combinatorial Puzzle meets CatsN-Queens Combinatorial Puzzle meets Cats
N-Queens Combinatorial Puzzle meets Cats
 
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
 
The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...
 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
 
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
 
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...
 
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
 
Jordan Peterson - The pursuit of meaning and related ethical axioms
Jordan Peterson - The pursuit of meaning and related ethical axiomsJordan Peterson - The pursuit of meaning and related ethical axioms
Jordan Peterson - The pursuit of meaning and related ethical axioms
 
Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...
Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...
Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...
 
Defining filter using (a) recursion (b) folding with S, B and I combinators (...
Defining filter using (a) recursion (b) folding with S, B and I combinators (...Defining filter using (a) recursion (b) folding with S, B and I combinators (...
Defining filter using (a) recursion (b) folding with S, B and I combinators (...
 
The Sieve of Eratosthenes - Part 1 - with minor corrections
The Sieve of Eratosthenes - Part 1 - with minor correctionsThe Sieve of Eratosthenes - Part 1 - with minor corrections
The Sieve of Eratosthenes - Part 1 - with minor corrections
 
The Sieve of Eratosthenes - Part 1
The Sieve of Eratosthenes - Part 1The Sieve of Eratosthenes - Part 1
The Sieve of Eratosthenes - Part 1
 
The Uniform Access Principle
The Uniform Access PrincipleThe Uniform Access Principle
The Uniform Access Principle
 
Computer Graphics in Java and Scala - Part 1b
Computer Graphics in Java and Scala - Part 1bComputer Graphics in Java and Scala - Part 1b
Computer Graphics in Java and Scala - Part 1b
 
The Expression Problem - Part 2
The Expression Problem - Part 2The Expression Problem - Part 2
The Expression Problem - Part 2
 
Computer Graphics in Java and Scala - Part 1
Computer Graphics in Java and Scala - Part 1Computer Graphics in Java and Scala - Part 1
Computer Graphics in Java and Scala - Part 1
 

Último

AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
VishalKumarJha10
 

Último (20)

Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
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 🔝✔️✔️
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
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 🔝✔️✔️
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
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
 
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
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 

Monad Fact #1

  • 1. MONAD FACT #1 Scala for comprehensions require a monad to be defined in terms of unit, map and flatMap rather than simply in terms of unit and flatMap @philip_schwarzslides by https://www.slideshare.net/pjschwarz
  • 2. sealed trait Option[+A] case object None extends Option[Nothing] case class Some[+A](get: A) extends Option[A] trait Monad[F[_]] { def flatMap[A,B](ma: F[A])(f: A => F[B]): F[B] def unit[A](a: => A): F[A] } val optionMonad = new Monad[Option] { def unit[A](a: => A): Option[A] = Some(a) def flatMap[A, B](ma: Option[A])(f: A => Option[B]): Option[B] = { ma match { case Some(a) => f(a) case None => None } } } One way to define a monad is with the following trait @philip_schwarz If we define a data structure, e.g. an Option we can then create a monad instance for Option by providing implementations for unit and flatMap
  • 3. def greeting(maybeGreeting: Option[String], maybeName: Option[String], maybeSurname: Option[String]): Option[String] = optionMonad.flatMap(maybeGreeting) { greeting => optionMonad.flatMap(maybeName) { name => optionMonad.flatMap(maybeSurname) { surname => optionMonad.unit(s"$greeting $name $surname!") } } } assert( greeting(maybeGreeting = Some("Hello"), maybeName = Some("Fred"), maybeSurname = Some("Smith")) == Some("Hello Fred Smith!")) assert( greeting(maybeGreeting = Some("Hello"), maybeName = None, maybeSurname = Some("Smith")) == None) Here is an example of using the Option monad instance
  • 4. We just saw how to define the Option monad by defining unit and flatMap functions that operate on Option. Another way of defining the Option monad is by adding map and flatMap functions to Option. @philip_schwarz If we do that, then we can take advantage of a great Scala feature that allows code that uses the monad to be much easier to understand than woud otherwise be the case. Here is how the greeting example looks like using this feature. sealed trait Option[+A] { def map[B](f: A => B): Option[B] = this match { case None => None case Some(a) => Some(f(a)) } def flatMap[B](f: A => Option[B]): Option[B] = this match { case None => None case Some(a) => f(a) } } case object None extends Option[Nothing] case class Some[+A](get: A) extends Option[A] def greeting(maybeGreeting: Option[String], maybeName: Option[String], maybeSurname: Option[String]): Option[String] = for { greeting <- maybeGreeting name <- maybeName surname <- maybeSurname } yield s"$greeting $name $surname!" assert(greeting(maybeGreeting = Some("Hello"), maybeName = Some("Fred"), maybeSurname = Some("Smith")) == Some("Hello Fred Smith!")) assert(greeting(maybeGreeting = Some("Hello"), maybeName = None, maybeSurname = Some("Smith")) == None)
  • 5. The feature in question is the ability to write an easy-to-understand for comprehension, whose syntactic sugar is translated by the Scala compiler into a harder-to-understand desugared chain of calls to map and flatMap maybeGreeting flatMap { greeting => maybeName flatMap { name => maybeSurname map { surname => s"$greeting $name $surname!" } } } for { greeting <- maybeGreeting name <- maybeName surname <- maybeSurname } yield s"$greeting $name $surname!” desugars to
  • 6. So why is it that in the first approach we can simply define a monad in terms of unit and flatMap whereas in the second approach we have to define a monad in terms of unit, map and flatMap? def map[B](f: A => B): Option[B] = def flatMap[B](f: A => Option[B]): Option[B] = case class Some[+A](get: A) extends Option[A] // Some acts as unit function def flatMap[A,B](ma: F[A])(f: A => F[B]): F[B] def unit[A](a: => A): F[A] On the first slide we defined a monad simply in terms of unit and flatMap. Later on, in order to take advantage of for comprehensions, we redefined a monad in terms of unit, map and flatMap. “We did not define a unit function!”, I hear you say. Well, although it is not called unit, we did define it: it is called Some, because creating a ‘defined’ Option, e.g. one with a value of 5, is done by evaluating Some(5) (to get hold of the ‘undefined’ Option we use None). @philip_schwarz
  • 7. The answer to that question is that is that in Scala there is no Monad trait that monads can implement and that the compiler is aware of, so the compiler does not know what the unit function of a monad is because for one thing, the function can have an arbitrary name. In this case the unit function is called Some, in the case of the Either monad it is called Right, in the case of the List monad it is called List, etc. If there were some convention by which the compiler could figure out what the unit function of a monad is, then rather than desugaring a for comprehension as follows: It could desugar it to something like this: maybeGreeting flatMap { greeting => maybeName flatMap { name => maybeSurname map { surname => s"$greeting $name $surname!" } } } for { greeting <- maybeGreeting name <- maybeName surname <- maybeSurname } yield s"$greeting $name $surname!” desugars to maybeGreeting flatMap { greeting => maybeName flatMap { name => maybeSurname flatMap { surname => monadInstance.unit(s"$greeting $name $surname!") } } } maybeGreeting flatMap { greeting => maybeName flatMap { name => maybeSurname flatMap { surname => Some(s"$greeting $name $surname!") } } }
  • 8. See the following for the list of all available slide decks in the MONAD FACT series https://www.slideshare.net/pjschwarz/the-monad-fact-slide-deck-series