Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Apéro Fonctionnel

Apéro Fonctionnel

Devoxx FR 2017
avec @CommitStrip_fr @nicolasleroux @waxzce @k33g_org

Philippe CHARRIERE

April 21, 2017
Tweet

More Decks by Philippe CHARRIERE

Other Decks in Programming

Transcript

  1. Bob

  2. 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();
  3. public class Container<T> { private T value; public T getValue()

    { return this.value; } public Container(T value) { this.value = value; } } Container
  4. Container | exemple Container bottle = new Container<String>(""); bottle.getValue(); //

    Container bob = new Container<String>(”Bob"); bob.getValue(); // Bob
  5. Functor public class Functor<T> extends Container { public Functor(T value)

    { super(value); } public <R> Functor<R> map(Function<T,R> f) { return new Functor<R>(f.apply((T) this.getValue())); } }
  6. Functor in action Functor<String> bouteilleMagique = new Functor<String>(""); Functor<String> autreBouteille

    = bouteilleMagique .map(contenu -> contenu + "") // plus de poire .map(contenu -> contenu + ""); // plus de poire System.out.println( autreBouteille.getValue() // );
  7. Functor in action bis Functor<String> content = new Functor<String>("Hello World")

    Functor<String> html = content .map(value -> "<h1>" + value + "</h1>") .map(value -> "<body>" + value + "</body>") .map(value -> "<html>" + value + "</html>"); System.out.println(html.getValue()); <html><body><h1>Hello World</h1></body></html>
  8. Functor | … dans un functor, dans un … Function<String,

    Functor<String>> ajouterPoire = contenu -> new Functor<String>(contenu + ""); bouteilleMagique .map(contenu -> new Functor<String>(contenu + "")) .getValue() // Functor@3e3abc88 Type attendu: Functor<Functor<String>> Puis: Functor<Functor<Functor<String>>> etc...
  9. Monad public class Monad<T> extends Container { public Monad(T value)

    { super(value); } public <R> Monad<R> map(Function<T,R> f) { return new Monad<R>(f.apply((T) this.getValue())); } public <R> Monad<R> flatMap(Function<T, Monad<R>> f) { return f.apply((T) this.getValue()); } }
  10. Monad | sample Monad<String> bouteilleMagique = new Monad<String>(""); System.out.println( autreBouteille

    .flatMap(contenu -> new Monad<String>(contenu + " ")) .flatMap(contenu -> new Monad<String>(contenu + " ")) .getValue() ); //
  11. Monad Identity in RL Monad<Double> prixDeDepart = new Monad<Double>(10000.0); //

    options Function<Double, Double> optionClim = prix -> prix + 2000.0 ; Function<Double, Double> interieurCuir = prix -> prix + 5000.0 ; Function<Double, Double> vitresTeintees = prix -> prix + 3000.0 ; Monad<Double> prixVoitureToutesOptions = prixDeDepart .map(optionClim) .map(interieurCuir) .map(vitresTeintees); System.out.println(prixVoitureToutesOptions.getValue()); // 20 000
  12. 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
  13. TinyToon class TinyToon { public String pseudo; public String avatar;

    public TinyToon(String pseudo, String avatar) { this.pseudo = pseudo; this.avatar = avatar; } }
  14. List<TinyToon> tinyToons = Arrays.asList( new TinyToon("Bob", ""), new TinyToon("Jane", ""),

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

    List<TinyToon> buddies; public TinyToon(String pseudo, String avatar) { this.pseudo = pseudo; this.avatar = avatar; } public TinyToon(String pseudo, String avatar, List<TinyToon> buddies) { this.pseudo = pseudo; this.avatar = avatar; this.buddies = buddies; } }
  16. List<TinyToon> 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", ""))) ); [ [, ], [, ], [, ], [, ] ]
  17. Je veux les avatars des buddies tinyToons.stream() .flatMap(toon -> toon.buddies.stream())

    .map(toon -> toon.avatar) .collect(Collectors.toList()) [ [, ], [, ], [, ], [, ] ] [“”, ””, ””, ””, ””, ””, ””, ””]
  18. 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
  19. Optional permet de modéliser null Optional<Poire> a 2 sous types

    / sous états Optional.of() Optional.empty() // pas de
  20. TinyToon class TinyToon { public String pseudo; public String avatar;

    public TinyToon(String pseudo, String avatar) { this.pseudo = pseudo; this.avatar = avatar; } }
  21. NPE before Function<Integer, TinyToon> getToon = key -> { Map<Integer,

    TinyToon> tinyToons = new HashMap<Integer, TinyToon>() {{ 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)
  22. NPE after (Java 8) Function<Integer, Optional<TinyToon>> getMayBeToon = key ->

    { Map<Integer, TinyToon> tinyToons = new HashMap<Integer, TinyToon>() {{ 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)); };
  23. 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("") //
  24. Optional + flatMap class LittleToon { public Optional<String> pseudo; public

    Optional<String> avatar; public LittleToon(String pseudo, String avatar) { this.pseudo = Optional.ofNullable(pseudo); this.avatar = Optional.ofNullable(avatar); } }
  25. Optional + flatMap Function<Integer, Optional<LittleToon>> getMayBeToon = key -> {

    Map<Integer, LittleToon> littleToons = new HashMap<Integer, LittleToon>() {{ 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)); };
  26. 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
  27. 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