Slide 1

Slide 1 text

Apéro fonctionnel

Slide 2

Slide 2 text

Bob

Slide 3

Slide 3 text

Bob public class Human { private String name; public Human(String name) { this.name = name; } public String getName() { return name; } } Human bob = new Human("Bob"); bob.getName();

Slide 4

Slide 4 text

Container

Slide 5

Slide 5 text

public class Container { private T value; public T getValue() { return this.value; } public Container(T value) { this.value = value; } } Container

Slide 6

Slide 6 text

Container | exemple Container bottle = new Container(""); bottle.getValue(); // Container bob = new Container(”Bob"); bob.getValue(); // Bob

Slide 7

Slide 7 text

Functor

Slide 8

Slide 8 text

Functor public class Functor extends Container { public Functor(T value) { super(value); } public Functor map(Function f) { return new Functor(f.apply((T) this.getValue())); } }

Slide 9

Slide 9 text

Functor in action Functor bouteilleMagique = new Functor(""); Functor autreBouteille = bouteilleMagique .map(contenu -> contenu + "") // plus de poire .map(contenu -> contenu + ""); // plus de poire System.out.println( autreBouteille.getValue() // );

Slide 10

Slide 10 text

.map(ajouterPoire) .map(ajouterPoire) .getValue()

Slide 11

Slide 11 text

Functor dans la vraie vie

Slide 12

Slide 12 text

Functor in action bis Functor content = new Functor("Hello World") Functor html = content .map(value -> "

" + value + "

") .map(value -> "" + value + "") .map(value -> "" + value + ""); System.out.println(html.getValue());

Hello World

Slide 13

Slide 13 text

Functor(Functor(Functor(…)))

Slide 14

Slide 14 text

Functor | … dans un functor, dans un … Function> ajouterPoire = contenu -> new Functor(contenu + ""); bouteilleMagique .map(contenu -> new Functor(contenu + "")) .getValue() // Functor@3e3abc88 Type attendu: Functor> Puis: Functor>> etc...

Slide 15

Slide 15 text

.map(ajouterPoire) .map(ajouterPoire)

Slide 16

Slide 16 text

Du coup la Monad Identity

Slide 17

Slide 17 text

Monad public class Monad extends Container { public Monad(T value) { super(value); } public Monad map(Function f) { return new Monad(f.apply((T) this.getValue())); } public Monad flatMap(Function> f) { return f.apply((T) this.getValue()); } }

Slide 18

Slide 18 text

Monad | sample Monad bouteilleMagique = new Monad(""); System.out.println( autreBouteille .flatMap(contenu -> new Monad(contenu + " ")) .flatMap(contenu -> new Monad(contenu + " ")) .getValue() ); //

Slide 19

Slide 19 text

.flatMap(ajouterPoire) .flatMap(ajouterPoire) .getValue()

Slide 20

Slide 20 text

Monade utile Identity

Slide 21

Slide 21 text

Monad Identity in RL Monad prixDeDepart = new Monad(10000.0); // options Function optionClim = prix -> prix + 2000.0 ; Function interieurCuir = prix -> prix + 5000.0 ; Function vitresTeintees = prix -> prix + 3000.0 ; Monad prixVoitureToutesOptions = prixDeDepart .map(optionClim) .map(interieurCuir) .map(vitresTeintees); System.out.println(prixVoitureToutesOptions.getValue()); // 20 000

Slide 22

Slide 22 text

Vous utilisez déjà des Monad(e)s

Slide 23

Slide 23 text

un stream a une map et une flatMap! Stream c’est une api qui utilise les lambdas et qui permet de faire des choses sympas avec les collections

Slide 24

Slide 24 text

.map()

Slide 25

Slide 25 text

TinyToon class TinyToon { public String pseudo; public String avatar; public TinyToon(String pseudo, String avatar) { this.pseudo = pseudo; this.avatar = avatar; } }

Slide 26

Slide 26 text

List tinyToons = Arrays.asList( new TinyToon("Bob", ""), new TinyToon("Jane", ""), new TinyToon("Sam", ""), new TinyToon("John", "") ); List myList = tinyToons .stream() .map(toon -> toon.pseudo + toon.avatar) .collect(Collectors.toList()); System.out.println(myList); // [“Bob“, “Jane“, “Sam“, “John“]

Slide 27

Slide 27 text

.flatMap()

Slide 28

Slide 28 text

class TinyToon { public String pseudo; public String avatar; public List buddies; public TinyToon(String pseudo, String avatar) { this.pseudo = pseudo; this.avatar = avatar; } public TinyToon(String pseudo, String avatar, List buddies) { this.pseudo = pseudo; this.avatar = avatar; this.buddies = buddies; } }

Slide 29

Slide 29 text

List tinyToons = Arrays.asList( new TinyToon("Bob", "", Arrays.asList( new TinyToon("Ted", ""), new TinyToon("Polo", ""))), new TinyToon("Jane", "", Arrays.asList( new TinyToon("Zed", ""), new TinyToon("Grou", ""))), new TinyToon("Sam", "", Arrays.asList( new TinyToon("Kate", ""), new TinyToon("Nike", ""))), new TinyToon("John", "", Arrays.asList( new TinyToon("Ray", ""), new TinyToon("Zoe", ""))) ); [ [, ], [, ], [, ], [, ] ]

Slide 30

Slide 30 text

Je veux les avatars des buddies tinyToons.stream() .flatMap(toon -> toon.buddies.stream()) .map(toon -> toon.avatar) .collect(Collectors.toList()) [ [, ], [, ], [, ], [, ] ] [“”, ””, ””, ””, ””, ””, ””, ””]

Slide 31

Slide 31 text

une autre super Monad(e) en Java 8: Optional Qui va nous servir à traiter les NPE

Slide 32

Slide 32 text

Le problème: c’est Null Ça ne veut pas dire grand chose Ce n’est pas vraiment un type Et poutrtant, out type en Java peut être null

Slide 33

Slide 33 text

Optional permet de modéliser null Optional a 2 sous types / sous états Optional.of() Optional.empty() // pas de

Slide 34

Slide 34 text

Optional.of( ) Optional.empty()

Slide 35

Slide 35 text

Mais repartons sur les toons …

Slide 36

Slide 36 text

TinyToon class TinyToon { public String pseudo; public String avatar; public TinyToon(String pseudo, String avatar) { this.pseudo = pseudo; this.avatar = avatar; } }

Slide 37

Slide 37 text

NPE before Function getToon = key -> { Map tinyToons = new HashMap() {{ put(1, new TinyToon("Bob", "")); put(2, new TinyToon("Jane", "")); put(3, new TinyToon("Sam", "")); put(4, new TinyToon("John", "")); }}; return tinyToons.get(key); }; System.out.println(getToon.apply(2).avatar); System.out.println(getToon.apply(4).avatar); System.out.println(getToon.apply(6).avatar); //⚠ le toon 6 n’existe pas > > > Exception in thread "main" java.lang.NullPointerException at SearchToons.main(SearchToons.java:20)

Slide 38

Slide 38 text

NPE after (Java 8) Function> getMayBeToon = key -> { Map tinyToons = new HashMap() {{ put(1, new TinyToon("Bob", "")); put(2, new TinyToon("Jane", "")); put(3, new TinyToon("Sam", "")); put(4, new TinyToon("John", "")); }}; return Optional.ofNullable(tinyToons.get(key)); };

Slide 39

Slide 39 text

NPE after (Java 8) getMayBeToon.apply(6) getMayBeToon.apply(3) Optional.empty Optional[TinyToon@3e3abc88] getMayBeToon.apply(6).map(toon -> toon.avatar) getMayBeToon.apply(3).map(toon -> toon.avatar) Optional.empty Optional[] getMayBeToon.apply(6).map(toon -> toon.avatar).orElse("") // getMayBeToon.apply(3).map(toon -> toon.avatar).orElse("") //

Slide 40

Slide 40 text

Optional + flatMap class LittleToon { public Optional pseudo; public Optional avatar; public LittleToon(String pseudo, String avatar) { this.pseudo = Optional.ofNullable(pseudo); this.avatar = Optional.ofNullable(avatar); } }

Slide 41

Slide 41 text

Optional + flatMap Function> getMayBeToon = key -> { Map littleToons = new HashMap() {{ put(1, new LittleToon("Bob", "")); put(2, new LittleToon("Jane", "")); put(3, new LittleToon("Sam", "")); put(4, new LittleToon("John", "")); }}; return Optional.ofNullable(littleToons.get(key)); };

Slide 42

Slide 42 text

Optional + flatMap getMayBeToon.apply(3).map(toon -> toon.avatar); Optional[Optional[]] getMayBeToon.apply(3).flatMap(toon -> toon.avatar); Optional[]

Slide 43

Slide 43 text

Either, another ❤ monad there is no Either with Java 8 A type with 2 sub-types

Slide 44

Slide 44 text

Either.right(pear) Either.left(bad pear) https://gist.github.com/k33g/011b1f22904c04462a98162c1a27c594 Either.isLeft() Either.isRight()

Slide 45

Slide 45 text

Catamorphisme toInt.apply("40").map(value -> value + 2) .cata(err -> { System.out.println(" ouille"); return 0; }, res -> { // right System.out.println(" yes: " + res); return res; }); // yes: 42

Slide 46

Slide 46 text

Catamorphisme toInt.apply("quarante-deux").map(value -> value + 2) .cata(err -> { System.out.println(" ouille"); return 0; }, res -> {// right System.out.println(" yes: " + res); return res; }); // ouille