SlideShare a Scribd company logo
filterA
a sighting of
in
@philip_schwarz
slides by http://fpilluminated.com/
by
Typelevel Rite of Passage
Build a Full-Stack Application with
Scala 3 and the Typelevel Stack
This deck is based on about 60 seconds of
a 35-hour video course called Typelevel
Right of Passage, an introduction to which
is available on YouTube.
@philip_schwarz
Daniel Ciocirlan
@rockthejvm
I am going to compare this user’s password against the hash that is already stored in the database.
/** Check against a bcrypt hash in a pure way
*
* It may raise an error for a malformed hash
*/
def checkpwBool[F[_]](password: String, hash: PasswordHash[A])
(implicit P: PasswordHasher[F, A]): F[Boolean] = …
def login(email: String, password: String): F[Option[JwtToken]] =
for
// find the user in the DB - return None if no user
maybeUser <- users.find(email)
// check password
maybeValidatedUser <- maybeUser.filter(user =>
BCrypt.checkpwBool[F](password, PasswordHash[BCrypt](user.hashedPassword)))
// Return a new token if password matches
maybeJwtToken <- maybeValidatedUser.traverse(user => authenticator.create(user.email))
yield maybeJwtToken
def find(email: String): F[Option[User]]
BCrypt
The Typelevel Rite of Passage
Daniel Ciocirlan
@rockthejvm
/** Check against a bcrypt hash in a pure way
*
* It may raise an error for a malformed hash
*/
def checkpwBool[F[_]](password: String, hash: PasswordHash[A])
(implicit P: PasswordHasher[F, A]): F[Boolean] = …
def login(email: String, password: String): F[Option[JwtToken]] =
for
// find the user in the DB - return None if no user
maybeUser <- users.find(email)
// check password
maybeValidatedUser <- maybeUser.filter(user =>
BCrypt.checkpwBool[F](password, PasswordHash[BCrypt](user.hashedPassword)))
// Return a new token if password matches
maybeJwtToken <- maybeValidatedUser.traverse(user => authenticator.create(user.email))
yield maybeJwtToken
def find(email: String): F[Option[User]]
However, the call to checkpwBool returns an F[Boolean], so our types are a little bit screwed up here.
BCrypt
The Typelevel Rite of Passage
Daniel Ciocirlan
@rockthejvm
/** Check against a bcrypt hash in a pure way
*
* It may raise an error for a malformed hash
*/
def checkpwBool[F[_]](password: String, hash: PasswordHash[A])
(implicit P: PasswordHasher[F, A]): F[Boolean] = …
def login(email: String, password: String): F[Option[JwtToken]] =
for
// find the user in the DB - return None if no user
maybeUser <- users.find(email)
// Option[User].filter(User => IO[Boolean]) => IO[Option[User]]
maybeValidatedUser <- maybeUser.filter(user =>
BCrypt.checkpwBool[F](password, PasswordHash[BCrypt](user.hashedPassword)))
// Return a new token if password matches
maybeJwtToken <- maybeValidatedUser.traverse(user => authenticator.create(user.email))
yield maybeJwtToken
def find(email: String): F[Option[User]]
We have an Option[User], and then I am going to call filter on a function User => IO[Boolean],
and I would need to return an IO[Option[User]], so that later I can use maybeValidatedUser.
BCrypt
The Typelevel Rite of Passage
Daniel Ciocirlan
@rockthejvm
At this point we have two improper types. One is the IO[Boolean], due to the fact that
filter does not accept a function returning an IO[Boolean], but rather a simple Boolean.
/** Check against a bcrypt hash in a pure way
*
* It may raise an error for a malformed hash
*/
def checkpwBool[F[_]](password: String, hash: PasswordHash[A])
(implicit P: PasswordHasher[F, A]): F[Boolean] = …
def login(email: String, password: String): F[Option[JwtToken]] =
for
// find the user in the DB - return None if no user
maybeUser <- users.find(email)
// Option[User].filter(User => IO[Boolean]) => IO[Option[User]]
maybeValidatedUser <- maybeUser.filter(user =>
BCrypt.checkpwBool[F](password, PasswordHash[BCrypt](user.hashedPassword)))
// Return a new token if password matches
maybeJwtToken <- maybeValidatedUser.traverse(user => authenticator.create(user.email))
yield maybeJwtToken
def find(email: String): F[Option[User]]
BCrypt
The Typelevel Rite of Passage
Daniel Ciocirlan
@rockthejvm
And the other is the return value of filter, because it is an
Option[User], rather than an effect wrapping Option[User].
/** Check against a bcrypt hash in a pure way
*
* It may raise an error for a malformed hash
*/
def checkpwBool[F[_]](password: String, hash: PasswordHash[A])
(implicit P: PasswordHasher[F, A]): F[Boolean] = …
def login(email: String, password: String): F[Option[JwtToken]] =
for
// find the user in the DB - return None if no user
maybeUser <- users.find(email)
// Option[User].filter(User => IO[Boolean]) => IO[Option[User]]
maybeValidatedUser <- maybeUser.filter(user =>
BCrypt.checkpwBool[F](password, PasswordHash[BCrypt](user.hashedPassword)))
// Return a new token if password matches
maybeJwtToken <- maybeValidatedUser.traverse(user => authenticator.create(user.email))
yield maybeJwtToken
def find(email: String): F[Option[User]]
BCrypt
The Typelevel Rite of Passage
Daniel Ciocirlan
@rockthejvm
Which is why I am going to use a little trick. I am going to call filterA, which is an extension method (I think it
comes from the Traverse typeclass).
On the Option of a particular type [e.g. User], you can call filterA with a function returning a different kind of
effect G wrapping a Boolean, so you’ll then return an effect G wrapping this Option[User].
/** Check against a bcrypt hash in a pure way
*
* It may raise an error for a malformed hash
*/
def checkpwBool[F[_]](password: String, hash: PasswordHash[A])
(implicit P: PasswordHasher[F, A]): F[Boolean] = …
def login(email: String, password: String): F[Option[JwtToken]] =
for
// find the user in the DB - return None if no user
maybeUser <- users.find(email)
// Option[User].filter(User => G[Boolean]) => G[Option[User]]
maybeValidatedUser <- maybeUser.filterA(user =>
BCrypt.checkpwBool[F](password, PasswordHash[BCrypt](user.hashedPassword)))
// Return a new token if password matches
maybeJwtToken <- maybeValidatedUser.traverse(user => authenticator.create(user.email))
yield maybeJwtToken
def find(email: String): F[Option[User]]
BCrypt
The Typelevel Rite of Passage
filterA is to traverse what filter is to map
Function From Given To Type Class
map F[A] A => B F[B] Functor[F]
filter F[A] A => Boolean F[A] FunctorFilter[F]
traverse F[A] A => G[B] G[F[B]] Traverse[F]
filterA F[A] A => G[Boolean] G[F[A]] TraverseFilter[F]
G is an Applicative (every Monad is an Applicative)
assert(List(1,2,3,4).map(_.toString) == List("1","2","3","4"))
def isEven(n: Int): Boolean = n % 2 == 0
assert(List(1,2,3,4).filter(isEven) == List(2,4))
def maybeDigit(c: Char): Option[Int] =
Option.when(c.isDigit)(c.asDigit)
assert(List('1','2','3','4').traverse(maybeDigit) == Some(List(1,2,3,4)))
assert(List('1','2','x','4').traverse(maybeDigit) == None)
def maybeEvenDigit(c: Char): Option[Boolean] =
maybeDigit(c).map(isEven)
assert(List('1','2','3','4').filterA(maybeEvenDigit) == Some(List('2','4')))
assert(List('1','2','x','4').filterA(maybeEvenDigit) == None)
map F[A] A => B F[B] Functor[F]
filterA F[A] A => G[Boolean] G[F[A]] TraverseFilter[F]
filter F[A] A => Boolean F[A] FunctorFilter[F]
traverse F[A] A => G[B] G[F[B]] Traverse[F]
A = Int
B = String
F = List
A = Char
B = Int
F = List
G = Option
Here are some
examples of using
map, filter, traverse,
and filterA.
filterA F[A] A => G[Boolean] G[F[A]]
filterA Option[User] User => IO[Boolean] IO[Option[User]]
Function From Given To
filterA List[Char] Char => Option[Boolean] Option[List[Char]]
def isEven(n: Int): Boolean = n % 2 == 0
def maybeDigit(c: Char): Option[Int] = Option.when(c.isDigit)(c.asDigit)
def maybeIsEvenDigit(c: Char): Option[Boolean] = maybeDigit(c).map(isEven)
assert(List('1','2','3','4').filterA(maybeIsEvenDigit) == Some(List('2','4')))
assert(List('1','2','x','4').filterA(maybeIsEvenDigit) == None)
def checkpwBool[F[_]](p: String, hash: PasswordHash[A])(implicit P: PasswordHasher[F, A]): F[Boolean] = …
for
// find the user in the DB - return None if no user
maybeUser <- users.findEmail(email)
// check password - Option[User].filter(User => IO[Boolean]) => IO[Option[User]]
maybeValidatedUser <- maybeUser.filterA(user =>
BCrypt.checkpwBool[F](p, PasswordHash[BCrypt](user.hashedPassword)))
Here we compare
our example of
using filterA, with
the usage of filterA
seen in the course.
Obviously the behaviour of filterA, which is reflected in its result, depends on the behaviour of a particular Applicative G.
So far we have seen examples with G = Option and G = IO.
Just as an example of the type of behaviour that we can achieve when G = List, here is a function that uses filterA to
compute the powerset of a set (the list of sublists of a list).
import cats.implicits.*
def powerset[A](as: List[A]): List[List[A]] = as.filterA(_ => List(true, false))
assert(powerset(List(1, 2, 3))
==
List(List(1, 2, 3),
List(1, 2),
List(1, 3),
List(1),
List(2, 3),
List(2),
List(3),
List()
)
)
A = Int
F = List
G = List
filterA F[A] A => G[Boolean] G[F[A]]
Function From Given To
filterA List[Int] Int => List[Boolean] List[List[Int]]
I just realised the using filterA to compute a powerset is
actually one of the examples in the documentation of filterA!
If you want to know more about how filterA works when computing the
powerset function, see slides 256 – 276 of the following slide deck.
map traverse
By the way, did you know that there is a further function that is a combination of
map and filter, and another one that is a combination of traverse and filterA?
@philip_schwarz
map traverse
Not surprisingly, the functions are called mapFilter and traverseFilter.
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
What about sequence, which is closely related to traverse?
Because sequence is just traverse(x => x), it doesn’t make sense for the sequence
equivalent of filterA to exist, but sequenceFilter does exist (see next slide).
traverse sequence
See next slide for a few more variations
of the example given above.
A Sighting of filterA in Typelevel Rite of Passage
In conclusion, the next slide recaps the signatures
of all the functions that we have mentioned.
@philip_schwarz
Function From Given To Type Class
map F[A] A => B F[B] Functor[F]
filter F[A] A => Boolean F[A] FunctorFilter[F] Apply a filter to a structure such that the
output structure contains all A elements
in the input structure that satisfy the
predicate f but none that don't.
mapFilter F[A] A => Option[B] F[B] FunctorFilter[F] A combined map and filter. Filtering is
handled via Option instead of Boolean
such that the output type B can be
different than the input type A.
traverse F[A] A => G[B] G[F[B]] Traverse[F] Given a function which returns a G
effect, thread this effect through the
running of this function on all the values
in F, returning an F[B] in a G context.
filterA F[A] A => G[Boolean] G[F[A]] TraverseFilter[F] Filter values inside a G context.
This is a generalized version of Haskell's
filterM . This StackOverflow question
about filterM may be helpful in
understanding how it behaves.
traverseFilter F[A] A => G[Option[B]] G[F[B]] TraverseFilter[F] A combined traverse and filter. Filtering
is handled via Option instead of Boolean
such that the output type B can be
different than the input type A.
sequence F[G[A]] G[F[A]] Traverse[F] Thread all the G effects through the F
structure to invert the structure from
F[G[A]] to G[F[A]].
sequenceFilter F[G[Option[A]] G[F[A]] TraverseFilter[F] traverseFilter with identity

More Related Content

Similar to A Sighting of filterA in Typelevel Rite of Passage

An Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using HaskellAn Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using Haskell
Michel Rijnders
 
Thumbtack Expertise Days # 5 - Javaz
Thumbtack Expertise Days # 5 - JavazThumbtack Expertise Days # 5 - Javaz
Thumbtack Expertise Days # 5 - Javaz
Alexey Remnev
 
(C++ programming)menu quit, book show, book change, book remo.docx
(C++ programming)menu  quit, book show, book change, book remo.docx(C++ programming)menu  quit, book show, book change, book remo.docx
(C++ programming)menu quit, book show, book change, book remo.docx
ajoy21
 
TDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
TDC218SP | Trilha Kotlin - DSLs in a Kotlin WayTDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
TDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
tdc-globalcode
 
How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF
Luc Bors
 
Django Forms: Best Practices, Tips, Tricks
Django Forms: Best Practices, Tips, TricksDjango Forms: Best Practices, Tips, Tricks
Django Forms: Best Practices, Tips, Tricks
Shawn Rider
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala
Knoldus Inc.
 
Angular 2 Component Communication - Talk by Rob McDiarmid
Angular 2 Component Communication - Talk by Rob McDiarmidAngular 2 Component Communication - Talk by Rob McDiarmid
Angular 2 Component Communication - Talk by Rob McDiarmid
Amrita Chopra
 
Creating a Facebook Clone - Part XXXI.pdf
Creating a Facebook Clone - Part XXXI.pdfCreating a Facebook Clone - Part XXXI.pdf
Creating a Facebook Clone - Part XXXI.pdf
ShaiAlmog1
 
Algebraic Data Types and Origami Patterns
Algebraic Data Types and Origami PatternsAlgebraic Data Types and Origami Patterns
Algebraic Data Types and Origami Patterns
Vasil Remeniuk
 
Python Development (MongoSF)
Python Development (MongoSF)Python Development (MongoSF)
Python Development (MongoSF)
Mike Dirolf
 
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
Cristina Delgado Rodríguez
 
Begin with Python
Begin with PythonBegin with Python
Begin with Python
Narong Intiruk
 
How te bring common UI patterns to ADF
How te bring common UI patterns to ADFHow te bring common UI patterns to ADF
How te bring common UI patterns to ADF
Getting value from IoT, Integration and Data Analytics
 
Python course Day 1
Python course Day 1Python course Day 1
Python course Day 1
Karin Lagesen
 
Funkcija, objekt, python
Funkcija, objekt, pythonFunkcija, objekt, python
Funkcija, objekt, python
Robert Lujo
 
C Programming Project
C Programming ProjectC Programming Project
C Programming Project
Vijayananda Mohire
 
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
takeoutweight
 
Event Sourcing and Functional Programming
Event Sourcing and Functional ProgrammingEvent Sourcing and Functional Programming
Event Sourcing and Functional Programming
GlobalLogic Ukraine
 
Functional Programming & Event Sourcing - a pair made in heaven
Functional Programming & Event Sourcing - a pair made in heavenFunctional Programming & Event Sourcing - a pair made in heaven
Functional Programming & Event Sourcing - a pair made in heaven
Pawel Szulc
 

Similar to A Sighting of filterA in Typelevel Rite of Passage (20)

An Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using HaskellAn Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using Haskell
 
Thumbtack Expertise Days # 5 - Javaz
Thumbtack Expertise Days # 5 - JavazThumbtack Expertise Days # 5 - Javaz
Thumbtack Expertise Days # 5 - Javaz
 
(C++ programming)menu quit, book show, book change, book remo.docx
(C++ programming)menu  quit, book show, book change, book remo.docx(C++ programming)menu  quit, book show, book change, book remo.docx
(C++ programming)menu quit, book show, book change, book remo.docx
 
TDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
TDC218SP | Trilha Kotlin - DSLs in a Kotlin WayTDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
TDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
 
How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF
 
Django Forms: Best Practices, Tips, Tricks
Django Forms: Best Practices, Tips, TricksDjango Forms: Best Practices, Tips, Tricks
Django Forms: Best Practices, Tips, Tricks
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala
 
Angular 2 Component Communication - Talk by Rob McDiarmid
Angular 2 Component Communication - Talk by Rob McDiarmidAngular 2 Component Communication - Talk by Rob McDiarmid
Angular 2 Component Communication - Talk by Rob McDiarmid
 
Creating a Facebook Clone - Part XXXI.pdf
Creating a Facebook Clone - Part XXXI.pdfCreating a Facebook Clone - Part XXXI.pdf
Creating a Facebook Clone - Part XXXI.pdf
 
Algebraic Data Types and Origami Patterns
Algebraic Data Types and Origami PatternsAlgebraic Data Types and Origami Patterns
Algebraic Data Types and Origami Patterns
 
Python Development (MongoSF)
Python Development (MongoSF)Python Development (MongoSF)
Python Development (MongoSF)
 
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
 
Begin with Python
Begin with PythonBegin with Python
Begin with Python
 
How te bring common UI patterns to ADF
How te bring common UI patterns to ADFHow te bring common UI patterns to ADF
How te bring common UI patterns to ADF
 
Python course Day 1
Python course Day 1Python course Day 1
Python course Day 1
 
Funkcija, objekt, python
Funkcija, objekt, pythonFunkcija, objekt, python
Funkcija, objekt, python
 
C Programming Project
C Programming ProjectC Programming Project
C Programming Project
 
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
 
Event Sourcing and Functional Programming
Event Sourcing and Functional ProgrammingEvent Sourcing and Functional Programming
Event Sourcing and Functional Programming
 
Functional Programming & Event Sourcing - a pair made in heaven
Functional Programming & Event Sourcing - a pair made in heavenFunctional Programming & Event Sourcing - a pair made in heaven
Functional Programming & Event Sourcing - a pair made in heaven
 

More from Philip Schwarz

Folding Cheat Sheet #7 - seventh in a series
Folding Cheat Sheet #7 - seventh in a seriesFolding Cheat Sheet #7 - seventh in a series
Folding Cheat Sheet #7 - seventh in a series
Philip Schwarz
 
Folding Cheat Sheet #6 - sixth in a series
Folding Cheat Sheet #6 - sixth in a seriesFolding Cheat Sheet #6 - sixth in a series
Folding Cheat Sheet #6 - sixth in a series
Philip Schwarz
 
Folding Cheat Sheet #5 - fifth in a series
Folding Cheat Sheet #5 - fifth in a seriesFolding Cheat Sheet #5 - fifth in a series
Folding Cheat Sheet #5 - fifth in a series
Philip Schwarz
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Philip Schwarz
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
Philip Schwarz
 
Folding Cheat Sheet #3 - third in a series
Folding Cheat Sheet #3 - third in a seriesFolding Cheat Sheet #3 - third in a series
Folding Cheat Sheet #3 - third in a series
Philip Schwarz
 
Folding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a seriesFolding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a series
Philip Schwarz
 
Folding Cheat Sheet #1 - first in a series
Folding Cheat Sheet #1 - first in a seriesFolding Cheat Sheet #1 - first in a series
Folding Cheat Sheet #1 - first in a series
Philip Schwarz
 
Scala Left Fold Parallelisation - Three Approaches
Scala Left Fold Parallelisation- Three ApproachesScala Left Fold Parallelisation- Three Approaches
Scala Left Fold Parallelisation - Three Approaches
Philip Schwarz
 
Tagless Final Encoding - Algebras and Interpreters and also Programs
Tagless Final Encoding - Algebras and Interpreters and also ProgramsTagless Final Encoding - Algebras and Interpreters and also Programs
Tagless Final Encoding - Algebras and Interpreters and also Programs
Philip Schwarz
 
Fusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with ViewsFusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with Views
Philip Schwarz
 
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
Philip Schwarz
 
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
Philip Schwarz
 
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
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
 
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...
Philip Schwarz
 
The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...
Philip Schwarz
 
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
Philip Schwarz
 
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
Philip Schwarz
 

More from Philip Schwarz (20)

Folding Cheat Sheet #7 - seventh in a series
Folding Cheat Sheet #7 - seventh in a seriesFolding Cheat Sheet #7 - seventh in a series
Folding Cheat Sheet #7 - seventh in a series
 
Folding Cheat Sheet #6 - sixth in a series
Folding Cheat Sheet #6 - sixth in a seriesFolding Cheat Sheet #6 - sixth in a series
Folding Cheat Sheet #6 - sixth in a series
 
Folding Cheat Sheet #5 - fifth in a series
Folding Cheat Sheet #5 - fifth in a seriesFolding Cheat Sheet #5 - fifth in a series
Folding Cheat Sheet #5 - fifth in a series
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
Folding Cheat Sheet #3 - third in a series
Folding Cheat Sheet #3 - third in a seriesFolding Cheat Sheet #3 - third in a series
Folding Cheat Sheet #3 - third in a series
 
Folding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a seriesFolding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a series
 
Folding Cheat Sheet #1 - first in a series
Folding Cheat Sheet #1 - first in a seriesFolding Cheat Sheet #1 - first in a series
Folding Cheat Sheet #1 - first in a series
 
Scala Left Fold Parallelisation - Three Approaches
Scala Left Fold Parallelisation- Three ApproachesScala Left Fold Parallelisation- Three Approaches
Scala Left Fold Parallelisation - Three Approaches
 
Tagless Final Encoding - Algebras and Interpreters and also Programs
Tagless Final Encoding - Algebras and Interpreters and also ProgramsTagless Final Encoding - Algebras and Interpreters and also Programs
Tagless Final Encoding - Algebras and Interpreters and also Programs
 
Fusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with ViewsFusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with Views
 
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
 

Recently uploaded

Il Data Streaming per un’AI real-time di nuova generazione
Il Data Streaming per un’AI real-time di nuova generazioneIl Data Streaming per un’AI real-time di nuova generazione
Il Data Streaming per un’AI real-time di nuova generazione
confluent
 
GT degree offer diploma Transcript
GT degree offer diploma TranscriptGT degree offer diploma Transcript
GT degree offer diploma Transcript
attueb
 
Comprehensive Vulnerability Assessments Process _ Aardwolf Security.docx
Comprehensive Vulnerability Assessments Process _ Aardwolf Security.docxComprehensive Vulnerability Assessments Process _ Aardwolf Security.docx
Comprehensive Vulnerability Assessments Process _ Aardwolf Security.docx
Aardwolf Security
 
Agra Girls Call Agra 0X0000000X Unlimited Short Providing Girls Service Avail...
Agra Girls Call Agra 0X0000000X Unlimited Short Providing Girls Service Avail...Agra Girls Call Agra 0X0000000X Unlimited Short Providing Girls Service Avail...
Agra Girls Call Agra 0X0000000X Unlimited Short Providing Girls Service Avail...
rachitkumar09887
 
bangalore Girls call 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
bangalore Girls call  👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Deliverybangalore Girls call  👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
bangalore Girls call 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
sunilverma7884
 
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdfA Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
kalichargn70th171
 
TEQnation 2024: Sustainable Software: May the Green Code Be with You
TEQnation 2024: Sustainable Software: May the Green Code Be with YouTEQnation 2024: Sustainable Software: May the Green Code Be with You
TEQnation 2024: Sustainable Software: May the Green Code Be with You
marcofolio
 
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
45unexpected
 
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
shanihomely
 
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
bhumivarma35300
 
當測試開始左移
當測試開始左移當測試開始左移
當測試開始左移
Jersey (CHE-PING) Su
 
SAP implementation steps PDF - Zyple Software
SAP implementation steps PDF - Zyple SoftwareSAP implementation steps PDF - Zyple Software
SAP implementation steps PDF - Zyple Software
Zyple Software
 
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
87tomato
 
Private Girls Call Navi Mumbai 🛵🚡9820252231 💃 Choose Best And Top Girl Servic...
Private Girls Call Navi Mumbai 🛵🚡9820252231 💃 Choose Best And Top Girl Servic...Private Girls Call Navi Mumbai 🛵🚡9820252231 💃 Choose Best And Top Girl Servic...
Private Girls Call Navi Mumbai 🛵🚡9820252231 💃 Choose Best And Top Girl Servic...
902basic
 
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdfAI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
Daniel Zivkovic
 
Girls Call Jogeshwari 9967584737 Provide Best And Top Girl Service And No1 in...
Girls Call Jogeshwari 9967584737 Provide Best And Top Girl Service And No1 in...Girls Call Jogeshwari 9967584737 Provide Best And Top Girl Service And No1 in...
Girls Call Jogeshwari 9967584737 Provide Best And Top Girl Service And No1 in...
simran hot girls
 
Top Chinese Government-backed APT Groups
Top Chinese Government-backed APT GroupsTop Chinese Government-backed APT Groups
Top Chinese Government-backed APT Groups
SOCRadar
 
Unleashing the Future: Building a Scalable and Up-to-Date GenAI Chatbot with ...
Unleashing the Future: Building a Scalable and Up-to-Date GenAI Chatbot with ...Unleashing the Future: Building a Scalable and Up-to-Date GenAI Chatbot with ...
Unleashing the Future: Building a Scalable and Up-to-Date GenAI Chatbot with ...
confluent
 
Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...
Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...
Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...
ashiklo9823
 
AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.
AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.
AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.
Srinivas Dukka
 

Recently uploaded (20)

Il Data Streaming per un’AI real-time di nuova generazione
Il Data Streaming per un’AI real-time di nuova generazioneIl Data Streaming per un’AI real-time di nuova generazione
Il Data Streaming per un’AI real-time di nuova generazione
 
GT degree offer diploma Transcript
GT degree offer diploma TranscriptGT degree offer diploma Transcript
GT degree offer diploma Transcript
 
Comprehensive Vulnerability Assessments Process _ Aardwolf Security.docx
Comprehensive Vulnerability Assessments Process _ Aardwolf Security.docxComprehensive Vulnerability Assessments Process _ Aardwolf Security.docx
Comprehensive Vulnerability Assessments Process _ Aardwolf Security.docx
 
Agra Girls Call Agra 0X0000000X Unlimited Short Providing Girls Service Avail...
Agra Girls Call Agra 0X0000000X Unlimited Short Providing Girls Service Avail...Agra Girls Call Agra 0X0000000X Unlimited Short Providing Girls Service Avail...
Agra Girls Call Agra 0X0000000X Unlimited Short Providing Girls Service Avail...
 
bangalore Girls call 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
bangalore Girls call  👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Deliverybangalore Girls call  👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
bangalore Girls call 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
 
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdfA Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
 
TEQnation 2024: Sustainable Software: May the Green Code Be with You
TEQnation 2024: Sustainable Software: May the Green Code Be with YouTEQnation 2024: Sustainable Software: May the Green Code Be with You
TEQnation 2024: Sustainable Software: May the Green Code Be with You
 
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
 
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
 
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
 
當測試開始左移
當測試開始左移當測試開始左移
當測試開始左移
 
SAP implementation steps PDF - Zyple Software
SAP implementation steps PDF - Zyple SoftwareSAP implementation steps PDF - Zyple Software
SAP implementation steps PDF - Zyple Software
 
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
 
Private Girls Call Navi Mumbai 🛵🚡9820252231 💃 Choose Best And Top Girl Servic...
Private Girls Call Navi Mumbai 🛵🚡9820252231 💃 Choose Best And Top Girl Servic...Private Girls Call Navi Mumbai 🛵🚡9820252231 💃 Choose Best And Top Girl Servic...
Private Girls Call Navi Mumbai 🛵🚡9820252231 💃 Choose Best And Top Girl Servic...
 
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdfAI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
 
Girls Call Jogeshwari 9967584737 Provide Best And Top Girl Service And No1 in...
Girls Call Jogeshwari 9967584737 Provide Best And Top Girl Service And No1 in...Girls Call Jogeshwari 9967584737 Provide Best And Top Girl Service And No1 in...
Girls Call Jogeshwari 9967584737 Provide Best And Top Girl Service And No1 in...
 
Top Chinese Government-backed APT Groups
Top Chinese Government-backed APT GroupsTop Chinese Government-backed APT Groups
Top Chinese Government-backed APT Groups
 
Unleashing the Future: Building a Scalable and Up-to-Date GenAI Chatbot with ...
Unleashing the Future: Building a Scalable and Up-to-Date GenAI Chatbot with ...Unleashing the Future: Building a Scalable and Up-to-Date GenAI Chatbot with ...
Unleashing the Future: Building a Scalable and Up-to-Date GenAI Chatbot with ...
 
Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...
Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...
Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...
 
AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.
AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.
AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.
 

A Sighting of filterA in Typelevel Rite of Passage

  • 1. filterA a sighting of in @philip_schwarz slides by http://fpilluminated.com/ by Typelevel Rite of Passage Build a Full-Stack Application with Scala 3 and the Typelevel Stack
  • 2. This deck is based on about 60 seconds of a 35-hour video course called Typelevel Right of Passage, an introduction to which is available on YouTube. @philip_schwarz
  • 3. Daniel Ciocirlan @rockthejvm I am going to compare this user’s password against the hash that is already stored in the database. /** Check against a bcrypt hash in a pure way * * It may raise an error for a malformed hash */ def checkpwBool[F[_]](password: String, hash: PasswordHash[A]) (implicit P: PasswordHasher[F, A]): F[Boolean] = … def login(email: String, password: String): F[Option[JwtToken]] = for // find the user in the DB - return None if no user maybeUser <- users.find(email) // check password maybeValidatedUser <- maybeUser.filter(user => BCrypt.checkpwBool[F](password, PasswordHash[BCrypt](user.hashedPassword))) // Return a new token if password matches maybeJwtToken <- maybeValidatedUser.traverse(user => authenticator.create(user.email)) yield maybeJwtToken def find(email: String): F[Option[User]] BCrypt The Typelevel Rite of Passage
  • 4. Daniel Ciocirlan @rockthejvm /** Check against a bcrypt hash in a pure way * * It may raise an error for a malformed hash */ def checkpwBool[F[_]](password: String, hash: PasswordHash[A]) (implicit P: PasswordHasher[F, A]): F[Boolean] = … def login(email: String, password: String): F[Option[JwtToken]] = for // find the user in the DB - return None if no user maybeUser <- users.find(email) // check password maybeValidatedUser <- maybeUser.filter(user => BCrypt.checkpwBool[F](password, PasswordHash[BCrypt](user.hashedPassword))) // Return a new token if password matches maybeJwtToken <- maybeValidatedUser.traverse(user => authenticator.create(user.email)) yield maybeJwtToken def find(email: String): F[Option[User]] However, the call to checkpwBool returns an F[Boolean], so our types are a little bit screwed up here. BCrypt The Typelevel Rite of Passage
  • 5. Daniel Ciocirlan @rockthejvm /** Check against a bcrypt hash in a pure way * * It may raise an error for a malformed hash */ def checkpwBool[F[_]](password: String, hash: PasswordHash[A]) (implicit P: PasswordHasher[F, A]): F[Boolean] = … def login(email: String, password: String): F[Option[JwtToken]] = for // find the user in the DB - return None if no user maybeUser <- users.find(email) // Option[User].filter(User => IO[Boolean]) => IO[Option[User]] maybeValidatedUser <- maybeUser.filter(user => BCrypt.checkpwBool[F](password, PasswordHash[BCrypt](user.hashedPassword))) // Return a new token if password matches maybeJwtToken <- maybeValidatedUser.traverse(user => authenticator.create(user.email)) yield maybeJwtToken def find(email: String): F[Option[User]] We have an Option[User], and then I am going to call filter on a function User => IO[Boolean], and I would need to return an IO[Option[User]], so that later I can use maybeValidatedUser. BCrypt The Typelevel Rite of Passage
  • 6. Daniel Ciocirlan @rockthejvm At this point we have two improper types. One is the IO[Boolean], due to the fact that filter does not accept a function returning an IO[Boolean], but rather a simple Boolean. /** Check against a bcrypt hash in a pure way * * It may raise an error for a malformed hash */ def checkpwBool[F[_]](password: String, hash: PasswordHash[A]) (implicit P: PasswordHasher[F, A]): F[Boolean] = … def login(email: String, password: String): F[Option[JwtToken]] = for // find the user in the DB - return None if no user maybeUser <- users.find(email) // Option[User].filter(User => IO[Boolean]) => IO[Option[User]] maybeValidatedUser <- maybeUser.filter(user => BCrypt.checkpwBool[F](password, PasswordHash[BCrypt](user.hashedPassword))) // Return a new token if password matches maybeJwtToken <- maybeValidatedUser.traverse(user => authenticator.create(user.email)) yield maybeJwtToken def find(email: String): F[Option[User]] BCrypt The Typelevel Rite of Passage
  • 7. Daniel Ciocirlan @rockthejvm And the other is the return value of filter, because it is an Option[User], rather than an effect wrapping Option[User]. /** Check against a bcrypt hash in a pure way * * It may raise an error for a malformed hash */ def checkpwBool[F[_]](password: String, hash: PasswordHash[A]) (implicit P: PasswordHasher[F, A]): F[Boolean] = … def login(email: String, password: String): F[Option[JwtToken]] = for // find the user in the DB - return None if no user maybeUser <- users.find(email) // Option[User].filter(User => IO[Boolean]) => IO[Option[User]] maybeValidatedUser <- maybeUser.filter(user => BCrypt.checkpwBool[F](password, PasswordHash[BCrypt](user.hashedPassword))) // Return a new token if password matches maybeJwtToken <- maybeValidatedUser.traverse(user => authenticator.create(user.email)) yield maybeJwtToken def find(email: String): F[Option[User]] BCrypt The Typelevel Rite of Passage
  • 8. Daniel Ciocirlan @rockthejvm Which is why I am going to use a little trick. I am going to call filterA, which is an extension method (I think it comes from the Traverse typeclass). On the Option of a particular type [e.g. User], you can call filterA with a function returning a different kind of effect G wrapping a Boolean, so you’ll then return an effect G wrapping this Option[User]. /** Check against a bcrypt hash in a pure way * * It may raise an error for a malformed hash */ def checkpwBool[F[_]](password: String, hash: PasswordHash[A]) (implicit P: PasswordHasher[F, A]): F[Boolean] = … def login(email: String, password: String): F[Option[JwtToken]] = for // find the user in the DB - return None if no user maybeUser <- users.find(email) // Option[User].filter(User => G[Boolean]) => G[Option[User]] maybeValidatedUser <- maybeUser.filterA(user => BCrypt.checkpwBool[F](password, PasswordHash[BCrypt](user.hashedPassword))) // Return a new token if password matches maybeJwtToken <- maybeValidatedUser.traverse(user => authenticator.create(user.email)) yield maybeJwtToken def find(email: String): F[Option[User]] BCrypt The Typelevel Rite of Passage
  • 9. filterA is to traverse what filter is to map Function From Given To Type Class map F[A] A => B F[B] Functor[F] filter F[A] A => Boolean F[A] FunctorFilter[F] traverse F[A] A => G[B] G[F[B]] Traverse[F] filterA F[A] A => G[Boolean] G[F[A]] TraverseFilter[F] G is an Applicative (every Monad is an Applicative)
  • 10. assert(List(1,2,3,4).map(_.toString) == List("1","2","3","4")) def isEven(n: Int): Boolean = n % 2 == 0 assert(List(1,2,3,4).filter(isEven) == List(2,4)) def maybeDigit(c: Char): Option[Int] = Option.when(c.isDigit)(c.asDigit) assert(List('1','2','3','4').traverse(maybeDigit) == Some(List(1,2,3,4))) assert(List('1','2','x','4').traverse(maybeDigit) == None) def maybeEvenDigit(c: Char): Option[Boolean] = maybeDigit(c).map(isEven) assert(List('1','2','3','4').filterA(maybeEvenDigit) == Some(List('2','4'))) assert(List('1','2','x','4').filterA(maybeEvenDigit) == None) map F[A] A => B F[B] Functor[F] filterA F[A] A => G[Boolean] G[F[A]] TraverseFilter[F] filter F[A] A => Boolean F[A] FunctorFilter[F] traverse F[A] A => G[B] G[F[B]] Traverse[F] A = Int B = String F = List A = Char B = Int F = List G = Option Here are some examples of using map, filter, traverse, and filterA.
  • 11. filterA F[A] A => G[Boolean] G[F[A]] filterA Option[User] User => IO[Boolean] IO[Option[User]] Function From Given To filterA List[Char] Char => Option[Boolean] Option[List[Char]] def isEven(n: Int): Boolean = n % 2 == 0 def maybeDigit(c: Char): Option[Int] = Option.when(c.isDigit)(c.asDigit) def maybeIsEvenDigit(c: Char): Option[Boolean] = maybeDigit(c).map(isEven) assert(List('1','2','3','4').filterA(maybeIsEvenDigit) == Some(List('2','4'))) assert(List('1','2','x','4').filterA(maybeIsEvenDigit) == None) def checkpwBool[F[_]](p: String, hash: PasswordHash[A])(implicit P: PasswordHasher[F, A]): F[Boolean] = … for // find the user in the DB - return None if no user maybeUser <- users.findEmail(email) // check password - Option[User].filter(User => IO[Boolean]) => IO[Option[User]] maybeValidatedUser <- maybeUser.filterA(user => BCrypt.checkpwBool[F](p, PasswordHash[BCrypt](user.hashedPassword))) Here we compare our example of using filterA, with the usage of filterA seen in the course.
  • 12. Obviously the behaviour of filterA, which is reflected in its result, depends on the behaviour of a particular Applicative G. So far we have seen examples with G = Option and G = IO. Just as an example of the type of behaviour that we can achieve when G = List, here is a function that uses filterA to compute the powerset of a set (the list of sublists of a list). import cats.implicits.* def powerset[A](as: List[A]): List[List[A]] = as.filterA(_ => List(true, false)) assert(powerset(List(1, 2, 3)) == List(List(1, 2, 3), List(1, 2), List(1, 3), List(1), List(2, 3), List(2), List(3), List() ) ) A = Int F = List G = List filterA F[A] A => G[Boolean] G[F[A]] Function From Given To filterA List[Int] Int => List[Boolean] List[List[Int]]
  • 13. I just realised the using filterA to compute a powerset is actually one of the examples in the documentation of filterA!
  • 14. If you want to know more about how filterA works when computing the powerset function, see slides 256 – 276 of the following slide deck.
  • 15. map traverse By the way, did you know that there is a further function that is a combination of map and filter, and another one that is a combination of traverse and filterA? @philip_schwarz
  • 16. map traverse Not surprisingly, the functions are called mapFilter and traverseFilter.
  • 19. What about sequence, which is closely related to traverse? Because sequence is just traverse(x => x), it doesn’t make sense for the sequence equivalent of filterA to exist, but sequenceFilter does exist (see next slide). traverse sequence
  • 20. See next slide for a few more variations of the example given above.
  • 22. In conclusion, the next slide recaps the signatures of all the functions that we have mentioned. @philip_schwarz
  • 23. Function From Given To Type Class map F[A] A => B F[B] Functor[F] filter F[A] A => Boolean F[A] FunctorFilter[F] Apply a filter to a structure such that the output structure contains all A elements in the input structure that satisfy the predicate f but none that don't. mapFilter F[A] A => Option[B] F[B] FunctorFilter[F] A combined map and filter. Filtering is handled via Option instead of Boolean such that the output type B can be different than the input type A. traverse F[A] A => G[B] G[F[B]] Traverse[F] Given a function which returns a G effect, thread this effect through the running of this function on all the values in F, returning an F[B] in a G context. filterA F[A] A => G[Boolean] G[F[A]] TraverseFilter[F] Filter values inside a G context. This is a generalized version of Haskell's filterM . This StackOverflow question about filterM may be helpful in understanding how it behaves. traverseFilter F[A] A => G[Option[B]] G[F[B]] TraverseFilter[F] A combined traverse and filter. Filtering is handled via Option instead of Boolean such that the output type B can be different than the input type A. sequence F[G[A]] G[F[A]] Traverse[F] Thread all the G effects through the F structure to invert the structure from F[G[A]] to G[F[A]]. sequenceFilter F[G[Option[A]] G[F[A]] TraverseFilter[F] traverseFilter with identity