SlideShare une entreprise Scribd logo
1  sur  90
Functor/Applicative/Traverse
… pour les débutant, promis !!
Functor, Applicative, Traverse queque tu racontes ??
Wesh, tu vas me laisser
tranquille avec ton Scala
j’y pige rien Functor,
Monad gneugneu
Sommaire
➔ Révisions sur les structures Option/Either
➔ Functor
➔ Applicative
➔ Traverse
Les révisions - Option
Option[A]
None
Some(value)
Les révisions - Either
Either[A,B]
Left(error)
Right(value)
Functor : Définition
‘contexte’ G catégorie A fonction f: A => B
Functor : Définition
Soit un ‘contexte’ G contenant une catégorie A et une
fonction f: A => B, ...
Functor : Définition
… un functor possède une méthode, permettant d’appliquer la
transformation f de la catégorie A vers une autre catégorie
B.
Functor : Définition
Functor : Définition
Functor : In real life
Functor : In real life
Functor : In real life
Functor : In real life
Functor: En scala
Functor: Specs - Maybe
Maybe[A]
Nothing
Just(value)
Functor: Specs - Maybe
Functor: Instance - Maybe
Functor: Instance - Maybe
Functor: Les lois - l’identité
Mapper la fonction identité sur un un contexte F est
équivalent au contexte lui-même.
Functor: Les lois - L’identité
Functor: Les lois - La composition
Mapper une fonction f puis mapper le résultat par une
fonction g équivaut à mapper une fois le résultat de la
fonction f à g
Functor: Les lois - La composition
Functor: Les lois - La composition
Functor: Les lois - La composition
Functor: La composition - Introduction
Functor: La composition - Introduction
Functor: La composition - Introduction
Functor: La composition - Introduction
Functor: La composition
Il est possible de mapper en une fois plusieurs functors
composés entre eux avec la méthode compose.
Functor: La composition
Functor: La composition
Functor: La composition
Functor: La composition
Functor: La composition
Functor: La composition
Functor: La composition
Functor
➔ Méthode map permet d’appliquer une fonction sur une
valeur contenue dans un contexte
➔ Loi identité et composition
➔ La composition des functors
Applicative - Les limites du Functor
Applicative - deux méthodes : pure
Applicative - deux méthodes : pure
Applicative - deux méthodes : ap ou <*>
Applicative - deux méthodes : ap ou <*>
Applicative - deux méthodes : ap ou <*>
Applicative - deux méthodes : ap ou <*>
Applicative - définition
Applicative - définition
Applicative: Specs - Maybe
Maybe[A]
Nothing
Just(value)
Applicative - Instance : Maybe
Applicative - Instance : Maybe
Applicative - Instance : Maybe
Applicative - Les lois
➔ Loi identité
➔ Loi composition
Applicative - Méthodes map(n)
GET api/expenses
GET api/salary
Service
salary - expenses
Applicative - Méthodes map(n)
GET api/expenses
GET api/salary
Service
salary - expenses
Applicative - Méthodes map(n)
Applicative - Méthodes map(n)
Applicative - Méthodes map(n)
Applicative - Méthodes map(n)
Applicative - Méthodes map(n)
Applicative - Cartesian - *> & <*
Applicative - in real life
3 règles de gestion :
➔ Vérifier l’image a été uploadée
➔ Vérifier l’image est carrée
➔ Vérifier les métadatas
Applicative - in real life
3 règles de gestion :
➔ Vérifier l’image a été uploadée => 100 ms + Net
➔ Vérifier l’image est carrée => 5ms
➔ Vérifier les métadatas => 5ms
Applicative - in real life
Applicative - in real life
Applicative - in real life
Right
Right(imageMetadata)
Applicative - in real life
Right
Right(imageMetadata)
Applicative - in real life
Right
Right(imageMetadata)
Applicative - in real life
Left(error)
Right(imageMetadata)
Applicative - in real life
Left(error)
Left(error)
Applicative
➔ Deux méthodes ap & pure
➔ L’Applicative est un Functor
➔ Loi identité & composition
Traverse - les limites de l’applicative
Traverse - les limites de l’applicative
Traverse - les limites de l’applicative
Limiter au nombre
de paramètre
Traverse - Introduction
Traverse - Introduction
Traverse - Méthode sequence
Traverse - Méthode sequence
Traverse - Méthode sequence
List( Right, Right, Left, Right, …, Right )
Précalculé
Traverse - une autre approche
List( “Paris”, “London”, “New York”, … , “Barcelona” )
Accumulateur: Right(List())
Traverse - une autre approche
List( “Paris”, “London”, “New York”, … , “Barcelona” )
getWeatherAPI
Accumulateur: Right(List())
Right(parisResult)
Traverse - une autre approche
List( “Paris”, “London”, “New York”, … , “Barcelona” )
getWeatherAPI
Accumulateur: Right(List(parisResult))
Right(londonResult)
Traverse - une autre approche
List( “Paris”, “London”, “New York”, … , “Barcelona” )
getWeatherAPI
Accumulateur: Right(List(parisResult, londonResult, …,
barcelonaResult))
Right(barcelonaResult)
Traverse - une autre approche
List( “Paris”, “London”, “New York”, … , “Barcelona” )
getWeatherAPI
Accumulateur: Right(List(parisResult))
Left
Traverse - une autre approche
List( “Paris”, “London”, “New York”, … , “Barcelona” )
getWeatherAPI
Accumulateur: Left(errorLondon)
Left
Traverse - une autre approche
➔ Initialisation accumulateur: Applicative.pure(List())
Traverse - une autre approche
➔ Initialisation accumulateur: Applicative.pure(List())
➔ L’accumulateur est une Applicative
Traverse - une autre approche
➔ Initialisation accumulateur: Applicative.pure(List())
➔ L’accumulateur est une Applicative
➔ Vérification résultat courant avec l’accumulateur & MAJ:
accumulateur.map2(resultat) { (acc, res) =>
acc ++ res
}
Traverse - méthode traverse
Conclusion
➔ Améliorer la visibilité du code
➔ Performance
➔ Meilleur compréhension des outils Scala
➔ Fun
Questions ?

Contenu connexe

Similaire à FP - Scala découverte Functor/Applicative/Traverse

Découvrez C# 4.0 et les améliorations apportées à la BCL
Découvrez C# 4.0 et les améliorations apportées à la BCLDécouvrez C# 4.0 et les améliorations apportées à la BCL
Découvrez C# 4.0 et les améliorations apportées à la BCLDotNetHub
 
laravel.sillo.org-Cours Laravel 10 les bases artisan et les contrôleurs_2.pdf
laravel.sillo.org-Cours Laravel 10  les bases  artisan et les contrôleurs_2.pdflaravel.sillo.org-Cours Laravel 10  les bases  artisan et les contrôleurs_2.pdf
laravel.sillo.org-Cours Laravel 10 les bases artisan et les contrôleurs_2.pdfHeartKing10
 
Php_Mysql.pdf
Php_Mysql.pdfPhp_Mysql.pdf
Php_Mysql.pdfETTAMRY
 
cours developpement web javascript 2023/2024
cours developpement web javascript 2023/2024cours developpement web javascript 2023/2024
cours developpement web javascript 2023/2024YounesOuladSayad1
 
Conception de base_de_l_algorithme
Conception de base_de_l_algorithmeConception de base_de_l_algorithme
Conception de base_de_l_algorithmemustapha4
 
02 Spécificité du C++ COURS SYS SYSSSSSS
02 Spécificité du C++  COURS SYS SYSSSSSS02 Spécificité du C++  COURS SYS SYSSSSSS
02 Spécificité du C++ COURS SYS SYSSSSSSAyoubElmrabet6
 
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...Normandy JUG
 
Ch2-Notions de base & actions élémentaires.pdf
Ch2-Notions de base & actions élémentaires.pdfCh2-Notions de base & actions élémentaires.pdf
Ch2-Notions de base & actions élémentaires.pdfFadouaBouafifSamoud
 
Visual Studio 2008 Overview
Visual Studio 2008 OverviewVisual Studio 2008 Overview
Visual Studio 2008 OverviewGregory Renard
 
Javascript ne se limite pas à jquery
Javascript ne se limite pas à jqueryJavascript ne se limite pas à jquery
Javascript ne se limite pas à jqueryneuros
 
PHP 7 et Symfony 3
PHP 7 et Symfony 3PHP 7 et Symfony 3
PHP 7 et Symfony 3Eddy RICHARD
 

Similaire à FP - Scala découverte Functor/Applicative/Traverse (16)

Découvrez C# 4.0 et les améliorations apportées à la BCL
Découvrez C# 4.0 et les améliorations apportées à la BCLDécouvrez C# 4.0 et les améliorations apportées à la BCL
Découvrez C# 4.0 et les améliorations apportées à la BCL
 
laravel.sillo.org-Cours Laravel 10 les bases artisan et les contrôleurs_2.pdf
laravel.sillo.org-Cours Laravel 10  les bases  artisan et les contrôleurs_2.pdflaravel.sillo.org-Cours Laravel 10  les bases  artisan et les contrôleurs_2.pdf
laravel.sillo.org-Cours Laravel 10 les bases artisan et les contrôleurs_2.pdf
 
Php_Mysql.pdf
Php_Mysql.pdfPhp_Mysql.pdf
Php_Mysql.pdf
 
algorithmique
algorithmiquealgorithmique
algorithmique
 
cours developpement web javascript 2023/2024
cours developpement web javascript 2023/2024cours developpement web javascript 2023/2024
cours developpement web javascript 2023/2024
 
Conception de base_de_l_algorithme
Conception de base_de_l_algorithmeConception de base_de_l_algorithme
Conception de base_de_l_algorithme
 
La première partie de la présentation PHP
La première partie de la présentation PHPLa première partie de la présentation PHP
La première partie de la présentation PHP
 
02 Spécificité du C++ COURS SYS SYSSSSSS
02 Spécificité du C++  COURS SYS SYSSSSSS02 Spécificité du C++  COURS SYS SYSSSSSS
02 Spécificité du C++ COURS SYS SYSSSSSS
 
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
 
Php4 Mysql
Php4 MysqlPhp4 Mysql
Php4 Mysql
 
Ch2-Notions de base & actions élémentaires.pdf
Ch2-Notions de base & actions élémentaires.pdfCh2-Notions de base & actions élémentaires.pdf
Ch2-Notions de base & actions élémentaires.pdf
 
Theme 7
Theme 7Theme 7
Theme 7
 
Visual Studio 2008 Overview
Visual Studio 2008 OverviewVisual Studio 2008 Overview
Visual Studio 2008 Overview
 
Javascript ne se limite pas à jquery
Javascript ne se limite pas à jqueryJavascript ne se limite pas à jquery
Javascript ne se limite pas à jquery
 
Chapitre 04 : les fonctions
Chapitre 04 : les fonctionsChapitre 04 : les fonctions
Chapitre 04 : les fonctions
 
PHP 7 et Symfony 3
PHP 7 et Symfony 3PHP 7 et Symfony 3
PHP 7 et Symfony 3
 

Dernier

GAL2024 - Consommations et productions d'énergies dans les exploitations lait...
GAL2024 - Consommations et productions d'énergies dans les exploitations lait...GAL2024 - Consommations et productions d'énergies dans les exploitations lait...
GAL2024 - Consommations et productions d'énergies dans les exploitations lait...Institut de l'Elevage - Idele
 
firefly algoriyhm sac a dos step by step .pdf
firefly algoriyhm sac a dos step by step .pdffirefly algoriyhm sac a dos step by step .pdf
firefly algoriyhm sac a dos step by step .pdffirstjob4
 
GAL2024 - Décarbonation du secteur laitier : la filière s'engage
GAL2024 - Décarbonation du secteur laitier : la filière s'engageGAL2024 - Décarbonation du secteur laitier : la filière s'engage
GAL2024 - Décarbonation du secteur laitier : la filière s'engageInstitut de l'Elevage - Idele
 
GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...
GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...
GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...Institut de l'Elevage - Idele
 
GAL2024 - L'élevage laitier cultive la biodiversité
GAL2024 - L'élevage laitier cultive la biodiversitéGAL2024 - L'élevage laitier cultive la biodiversité
GAL2024 - L'élevage laitier cultive la biodiversitéInstitut de l'Elevage - Idele
 
GAL2024 - Méthane 2030 : une démarche collective française à destination de t...
GAL2024 - Méthane 2030 : une démarche collective française à destination de t...GAL2024 - Méthane 2030 : une démarche collective française à destination de t...
GAL2024 - Méthane 2030 : une démarche collective française à destination de t...Institut de l'Elevage - Idele
 
GAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenus
GAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenusGAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenus
GAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenusInstitut de l'Elevage - Idele
 
GAL2024 - Changements climatiques et maladies émergentes
GAL2024 - Changements climatiques et maladies émergentesGAL2024 - Changements climatiques et maladies émergentes
GAL2024 - Changements climatiques et maladies émergentesInstitut de l'Elevage - Idele
 
conception d'un batiment r+4 comparative de defferente ariante de plancher
conception d'un  batiment  r+4 comparative de defferente ariante de plancherconception d'un  batiment  r+4 comparative de defferente ariante de plancher
conception d'un batiment r+4 comparative de defferente ariante de planchermansouriahlam
 
comprehension de DDMRP dans le domaine de gestion
comprehension de DDMRP dans le domaine de gestioncomprehension de DDMRP dans le domaine de gestion
comprehension de DDMRP dans le domaine de gestionyakinekaidouchi1
 
GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...
GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...
GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...Institut de l'Elevage - Idele
 
optimisation logistique MLT_231102_155827.pdf
optimisation logistique  MLT_231102_155827.pdfoptimisation logistique  MLT_231102_155827.pdf
optimisation logistique MLT_231102_155827.pdfSoukainaMounawir
 
GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...
GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...
GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...Institut de l'Elevage - Idele
 
Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024
Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024
Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024Ville de Châteauguay
 

Dernier (15)

GAL2024 - Consommations et productions d'énergies dans les exploitations lait...
GAL2024 - Consommations et productions d'énergies dans les exploitations lait...GAL2024 - Consommations et productions d'énergies dans les exploitations lait...
GAL2024 - Consommations et productions d'énergies dans les exploitations lait...
 
firefly algoriyhm sac a dos step by step .pdf
firefly algoriyhm sac a dos step by step .pdffirefly algoriyhm sac a dos step by step .pdf
firefly algoriyhm sac a dos step by step .pdf
 
GAL2024 - Décarbonation du secteur laitier : la filière s'engage
GAL2024 - Décarbonation du secteur laitier : la filière s'engageGAL2024 - Décarbonation du secteur laitier : la filière s'engage
GAL2024 - Décarbonation du secteur laitier : la filière s'engage
 
GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...
GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...
GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...
 
GAL2024 - L'élevage laitier cultive la biodiversité
GAL2024 - L'élevage laitier cultive la biodiversitéGAL2024 - L'élevage laitier cultive la biodiversité
GAL2024 - L'élevage laitier cultive la biodiversité
 
JTC 2024 Bâtiment et Photovoltaïque.pdf
JTC 2024  Bâtiment et Photovoltaïque.pdfJTC 2024  Bâtiment et Photovoltaïque.pdf
JTC 2024 Bâtiment et Photovoltaïque.pdf
 
GAL2024 - Méthane 2030 : une démarche collective française à destination de t...
GAL2024 - Méthane 2030 : une démarche collective française à destination de t...GAL2024 - Méthane 2030 : une démarche collective française à destination de t...
GAL2024 - Méthane 2030 : une démarche collective française à destination de t...
 
GAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenus
GAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenusGAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenus
GAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenus
 
GAL2024 - Changements climatiques et maladies émergentes
GAL2024 - Changements climatiques et maladies émergentesGAL2024 - Changements climatiques et maladies émergentes
GAL2024 - Changements climatiques et maladies émergentes
 
conception d'un batiment r+4 comparative de defferente ariante de plancher
conception d'un  batiment  r+4 comparative de defferente ariante de plancherconception d'un  batiment  r+4 comparative de defferente ariante de plancher
conception d'un batiment r+4 comparative de defferente ariante de plancher
 
comprehension de DDMRP dans le domaine de gestion
comprehension de DDMRP dans le domaine de gestioncomprehension de DDMRP dans le domaine de gestion
comprehension de DDMRP dans le domaine de gestion
 
GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...
GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...
GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...
 
optimisation logistique MLT_231102_155827.pdf
optimisation logistique  MLT_231102_155827.pdfoptimisation logistique  MLT_231102_155827.pdf
optimisation logistique MLT_231102_155827.pdf
 
GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...
GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...
GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...
 
Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024
Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024
Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024
 

FP - Scala découverte Functor/Applicative/Traverse

Notes de l'éditeur

  1. https://carbon.now.sh/?bg=rgba(171%2C%20184%2C%20195%2C%201)&t=base16-light&wt=bw&l=text%2Fx-scala&ds=false&dsyoff=20px&dsblur=68px&wc=false&wa=true&pv=0px&ph=0px&ln=false&fm=dm&fs=18px&lh=176%25&si=false&code=def%2520getItems(weatherDeparture%253A%2520Weather%255BInfo%255D%252C%2520%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520weatherTerminal%253A%2520Weather%255BInfo%255D)%253A%2520Either%255BError%252C%2520List%255BItems%255D%255D%250A%250Aval%2520weatherBarcelona%253A%2520Weather%255BInfo%255D%2520%253D%2520Sunny(Info(%2522Barcelona%2522%252C%252025.0))%250Aval%2520weatherMTP%253A%2520Weather%255BInfo%255D%2520%253D%2520Sunny(Info(%2522Montpellier%2522%252C%252020.0))%250A%250A(weatherBarcelona%252C%2520weatherMTP).map2((wB%252C%2520wM)%2520%253D%253E%2520getItems(wB%252C%2520wMTP))&es=2x&wm=false
  2. Nom compliqué pour des concepts relativement simple
  3. TODO a decomposer
  4. TODO a decomposer
  5. TODO a decomposer
  6. TODO a decomposer
  7. Just("Hello").map(_ + " world") // Just("Hello world") Nothing.map(_ + " world") // Nothing
  8. VIRER =
  9. new Functor[Maybe] = { override def map[A, B](maybeA: Maybe[A])(f: A => B) = { maybeA match { case Just(value) => Maybe(f(value)) case Nothing => Nothing } } }
  10. def compute(): Either[Error, List[Int]] def plus3(x: Int): Int = x + 3 val result = compute() result.map(_map(x => plus3(x)))
  11. def compute(): Either[Error, List[Int]] def plus3(x: Int): Int = x + 3 val result = compute() result.map(_map(x => plus3(x)))
  12. def compute(): Either[Error, List[Int]] def plus3(x: Int): Int = x + 3 val result = compute() result.map(_map(x => plus3(x)))
  13. case class DisplayItem(name: String, price: Double) def getItems: IO[Either[Error, List[Items]]] = ??? def displayItemsToClient = Functor[IO] .compose[Either[Error, ?]] .compose[List] .map(item => ItemInfo(item.name, item.price * 2.5))
  14. case class DisplayItem(name: String, price: Double) def getItems: IO[Either[Error, List[Items]]] = ??? def displayItemsToClient = Functor[IO] .compose[Either[Error, ?]] .compose[List] .map(item => ItemInfo(item.name, item.price * 2.5))
  15. case class DisplayItem(name: String, price: Double) def getItems: IO[Either[Error, List[Items]]] = ??? def displayItemsToClient = Functor[IO] .compose[Either[Error, ?]] .compose[List] .map(item => ItemInfo(item.name, item.price * 2.5))
  16. case class DisplayItem(name: String, price: Double) def getItems: IO[Either[Error, List[Items]]] = ??? def displayItemsToClient = Functor[IO] .compose[Either[Error, ?]] .compose[List] .map(item => ItemInfo(item.name, item.price * 2.5))
  17. A supprimer
  18. def plus3(x: Int): Int = x + 3 Right(7) <*> Right(plus3) // Right(10) Left("An error occurred") <*> Right(plus3) // Left("An error occurred")
  19. TODO trait Applicative[F[_]] extends Functor[F] { def pure[A](a: A): F[A] def ap[A, B](ff: F[A => B])(fa: F[A]): F[B] def map[A, B](fa: F[A])(f: A => B): F[B] }
  20. TODO trait Applicative[F[_]] extends Functor[F] { def pure[A](a: A): F[A] def ap[A, B](ff: F[A => B])(fa: F[A]): F[B] def map[A, B](fa: F[A])(f: A => B): F[B] }
  21. new Applicative[Maybe] { def pure[A](a: A): Maybe[A] = Maybe(a) def ap[A, B](maybeF: Maybe[A => B])(maybeA: A): Maybe[B] = { (maybeF, maybeA) match { case (Just(f), Just(a)) => pure(f(a)) case _ => Nothing } } }
  22. new Applicative[Maybe] { def pure[A](a: A): Maybe[A] = Maybe(a) def ap[A, B](maybeF: Maybe[A => B])(maybeA: A): Maybe[B] = { (maybeF, maybeA) match { case (Just(f), Just(a)) => pure(f(a)) case _ => Nothing } } }
  23. new Applicative[Maybe] { def pure[A](a: A): Maybe[A] = Maybe(a) def ap[A, B](maybeF: Maybe[A => B])(maybeA: A): Maybe[B] = { (maybeF, maybeA) match { case (Just(f), Just(a)) => pure(f(a)) case _ => Nothing } } }
  24. def getMyExpenses(credential: Credential): Either[Error, Double] def getMySalary(credential: Credential): Either[Error, Double] def process(credential: Credential): Either[Error, Double] = { val expensesEither = getMyExpenses(credential) val salaryEither = getMySalary(credential) (expensesEither, salaryEither) match { case (Right(expenses), Right(salary)) => Right(expenses + salary) case (Left(error), _) => Left(error) case (_, Left(error)) => Left(error) } }
  25. def getMyExpenses(credential: Credential): Either[Error, Double] def getMySalary(credential: Credential): Either[Error, Double] def process(credential: Credential): Either[Error, Double] = { val expensesEither = getMyExpenses(credential) val salaryEither = getMySalary(credential) (expensesEither, salaryEither) match { case (Right(expenses), Right(salary)) => Right(expenses + salary) case (Left(error), _) => Left(error) case (_, Left(error)) => Left(error) } }
  26. def getMyExpenses(credential: Credential): Either[Error, Double] def getMySalary(credential: Credential): Either[Error, Double] def process(credential: Credential): Either[Error, Double] = { val expensesEither = getMyExpenses(credential) val salaryEither = getMySalary(credential) (expensesEither, salaryEither) match { case (Right(expenses), Right(salary)) => Right(expenses + salary) case (Left(error), _) => Left(error) case (_, Left(error)) => Left(error) } }
  27. def getMyExpenses(credential: Credential): Either[Error, Double] def getMySalary(credential: Credential): Either[Error, Double] def process(credential: Credential): Either[Error, Double] = { val expensesEither = getMyExpenses(credential) val salaryEither = getMySalary(credential) (expensesEither, salaryEither) match { case (Right(expenses), Right(salary)) => Right(expenses + salary) case (Left(error), _) => Left(error) case (_, Left(error)) => Left(error) } }
  28. def getMyExpenses(credential: Credential): Either[Error, Double] def getMySalary(credential: Credential): Either[Error, Double] def process(credential: Credential): Either[Error, Double] = { val expensesEither = getMyExpenses(credential) val salaryEither = getMySalary(credential) (expensesEither, salaryEither) match { case (Right(expenses), Right(salary)) => Right(expenses + salary) case (Left(error), _) => Left(error) case (_, Left(error)) => Left(error) } }
  29. def getMyExpenses(credential: Credential): Either[Error, Double] def getMySalary(credential: Credential): Either[Error, Double] def getVariousIncome(credential: Credential): Either[Error, Double] def process(credential: Credential): Either[Error, Double] = { val expensesEither = getMyExpenses(credential) val salaryEither = getMySalary(credential) val otherEither = getVariousIncome(credential) Applicative[Either[Error, ?]] .map2(expensesEither, salaryEither)((expenses, salary) => salary - expenses) Applicative[Either[Error, ?]] .map3(expensesEither, salaryEither, otherEither) { (expenses, salary, other) => salary + other - expenses } ... Applicative[Either[Error, ?]] .map22(...)(_ => ...) }
  30. A detailler def isUploadToS3(id: ImageId): Either[Error, URI] // 100ms + NET def isSquare(size: Size): Either[Error, Size] // 5ms def validateMetadata(image: Image): Either[Error, Metadata] // 5ms def validateImageAndExtractMetadata(image: Image): Either[Error, Metadata] = { validateMetadata(image) *> isSquare(image.size) >* isUploadToS3(image.id) }
  31. A detailler def isUploadToS3(id: ImageId): Either[Error, URI] // 100ms + NET def isSquare(size: Size): Either[Error, Size] // 5ms def validateMetadata(image: Image): Either[Error, Metadata] // 5ms def validateImageAndExtractMetadata(image: Image): Either[Error, Metadata] = { validateMetadata(image) *> isSquare(image.size) >* isUploadToS3(image.id) }
  32. A detailler def isUploadToS3(id: ImageId): Either[Error, URI] // 100ms + NET def isSquare(size: Size): Either[Error, Size] // 5ms def validateMetadata(image: Image): Either[Error, Metadata] // 5ms def validateImageAndExtractMetadata(image: Image): Either[Error, Metadata] = { validateMetadata(image) *> isSquare(image.size) >* isUploadToS3(image.id) }
  33. def isUploadToS3(id: ImageId): Either[Error, URI] // 100ms + NET def isSquare(size: Size): Either[Error, Size] // 5ms def validateMetadata(image: Image): Either[Error, Metadata] // 5ms def validateImageAndExtractMetadata(image: Image): Either[Error, Metadata] = { validateMetadata(image) *> isSquare(image.size) >* isUploadToS3(image.id) }
  34. def isUploadToS3(id: ImageId): Either[Error, URI] // 100ms + NET def isSquare(size: Size): Either[Error, Size] // 5ms def validateMetadata(image: Image): Either[Error, Metadata] // 5ms def validateImageAndExtractMetadata(image: Image): Either[Error, Metadata] = { validateMetadata(image) *> isSquare(image.size) >* isUploadToS3(image.id) }
  35. def isUploadToS3(id: ImageId): Either[Error, URI] // 100ms + NET def isSquare(size: Size): Either[Error, Size] // 5ms def validateMetadata(image: Image): Either[Error, Metadata] // 5ms def validateImageAndExtractMetadata(image: Image): Either[Error, Metadata] = { validateMetadata(image) *> isSquare(image.size) >* isUploadToS3(image.id) }
  36. def isUploadToS3(id: ImageId): Either[Error, URI] // 100ms + NET def isSquare(size: Size): Either[Error, Size] // 5ms def validateMetadata(image: Image): Either[Error, Metadata] // 5ms def validateImageAndExtractMetadata(image: Image): Either[Error, Metadata] = { validateMetadata(image) *> isSquare(image.size) >* isUploadToS3(image.id) }
  37. def isUploadToS3(id: ImageId): Either[Error, URI] // 100ms + NET def isSquare(size: Size): Either[Error, Size] // 5ms def validateMetadata(image: Image): Either[Error, Metadata] // 5ms def validateImageAndExtractMetadata(image: Image): Either[Error, Metadata] = { validateMetadata(image) *> isSquare(image.size) >* isUploadToS3(image.id) }
  38. def isUploadToS3(id: ImageId): Either[Error, URI] // 100ms + NET def isSquare(size: Size): Either[Error, Size] // 5ms def validateMetadata(image: Image): Either[Error, Metadata] // 5ms def validateImageAndExtractMetadata(image: Image): Either[Error, Metadata] = { validateMetadata(image) *> isSquare(image.size) >* isUploadToS3(image.id) }
  39. Detailler calculs independants
  40. def getWeatherAPI(city: String): Either[Error, Weather] def getWeather(cityA: String, cityB: String): Either[Error, (Weather, Weather)] = Applicative[Either[Error, ?]].tuple2(cityA, cityB)
  41. def getWeatherAPI(city: String): Either[Error, Weather] def getWeather(cityA: String, cityB: String, cityC: String): Either[Error, (Weather, Weather, Weather)] = Applicative[Either[Error, ?]].tuple2(cityA, cityB, cityC)
  42. def getWeatherAPI(city: String): Either[Error, Weather] def getWeather(cityA: String, cityB: String, cityC: String): Either[Error, (Weather, Weather, Weather)] = Applicative[Either[Error, ?]].tuple2(cityA, cityB, cityC)
  43. FAUX def getWeatherAPI(city: String): Either[Error, Weather] def getWeather(cities: String*): Either[Error, Seq[Weather]] = { cities.map(city => getWeatherAPI(city)) // List[Either[Error, Seq[Weather]]] }
  44. def getWeatherAPI(city: String): Either[Error, Weather] def getWeather(cityA: String, cityB: String, cityC: String): Either[Error, (Weather, Weather, Weather)] = Applicative[Either[Error, ?]].tuple2(cityA, cityB, cityC)
  45. List(Some(1), Some(2), Some(3)).sequence // Option(List(1, 2, 3)) List(Some(1), None, Some(3)).sequence // None List(Right("Felix"), Right("Jean"), Right("Rex")).sequence // Right(List("Felix", "Jean", "Rex")) List(Left, Right("Jean"), Right("Rex")).sequence // Left
  46. def getWeatherAPI(city: String): Either[Error, Weather] def getWeather(cities: String*): Either[Error, Seq[Weather]] = { cities.map(city => getWeatherAPI(city)).toList.sequence }
  47. def getWeatherAPI(city: String): Either[Error, Weather] def getWeather(cities: String*): Either[Error, Seq[Weather]] = { cities.map(city => getWeatherAPI(city)).toList.sequence }
  48. def getWeatherAPI(city: String): Either[Error, Weather] def getWeather(cities: String*): Either[Error, Seq[Weather]] = { cities.map(city => getWeatherAPI(city)).toList.sequence }
  49. def getWeatherAPI(city: String): Either[Error, Weather] def getWeather(cities: String*): Either[Error, Seq[Weather]] = { cities.map(city => getWeatherAPI(city)).toList.sequence }
  50. def getWeatherAPI(city: String): Either[Error, Weather] def getWeather(cities: String*): Either[Error, Seq[Weather]] = { cities.map(city => getWeatherAPI(city)).toList.sequence }
  51. def getWeatherAPI(city: String): Either[Error, Weather] def getWeather(cities: String*): Either[Error, Seq[Weather]] = { cities.map(city => getWeatherAPI(city)).toList.sequence }
  52. def getWeatherAPI(city: String): Either[Error, Weather] def getWeather(cities: String*): Either[Error, Seq[Weather]] = { cities.map(city => getWeatherAPI(city)).toList.sequence }
  53. def getWeatherAPI(city: String): Either[Error, Weather] def getWeather(cities: String*): Either[Error, Seq[Weather]] = { cities.map(city => getWeatherAPI(city)).toList.sequence }
  54. def getWeatherAPI(city: String): Either[Error, Weather] def getWeather(cities: String*): Either[Error, Seq[Weather]] = { cities.toList.traverse[Either[Error, ?], String, Weather] { city => getWeatherAPI(city) } }