diff --git a/src/css/minimalist.css b/src/css/minimalist.css
index e96984e..cd1e9bc 100644
--- a/src/css/minimalist.css
+++ b/src/css/minimalist.css
@@ -218,7 +218,7 @@ navigation > a {
margin-top: 10px;
}
#content,.content {
- max-width: 50em;
+ max-width: 51em;
margin: 0 1em;
padding: 1px;
}
diff --git a/src/css/slides.css b/src/css/slides.css
index 25c9cce..e79901c 100644
--- a/src/css/slides.css
+++ b/src/css/slides.css
@@ -12,3 +12,6 @@
margin: 1em 0;
text-align: center;
}
+#content,.content {
+ max-width: 53em !important;
+}
diff --git a/src/slides.org b/src/slides.org
index a5fcf2a..ffa87f6 100644
--- a/src/slides.org
+++ b/src/slides.org
@@ -14,3 +14,9 @@
about how to gain back autonomy with git by providing most features
Github propose just with a few conventions. I even written a tool to help
manage issues, code review, git hosting, etc...
+
+** French talks
+
+- [2018-03-15 Thu]
+ [[file:slides/Intro-to-FP-with-Haskell.org][Introduction à la programmation fonctionnelle avec Haskell]]
+ is a small French talk introducing Haskell.
diff --git a/src/slides/Intro-to-FP-with-Haskell.org b/src/slides/Intro-to-FP-with-Haskell.org
new file mode 100644
index 0000000..9a586a7
--- /dev/null
+++ b/src/slides/Intro-to-FP-with-Haskell.org
@@ -0,0 +1,894 @@
+#+Title: Introduction à la Programmation Fonctionnelle avec Haskell
+#+Author: Yann Esposito
+#+Email: yann@esposito.host
+#+Date: <2018-03-15 Thu>
+#+LANGUAGE: fr
+#+LANG: fr
+#+HTML_HEAD:
+* Introduction à la Programmation Fonctionnelle avec Haskell
+*** main :: IO ()
+
+#+BEGIN_SRC
+████████████████████████████████████████████████████████████████████████████████████
+█ █
+█ Initialiser l'env de dev █
+█ █
+████████████████████████████████████████████████████████████████████████████████████
+#+END_SRC
+
+Install **stack**:
+
+#+BEGIN_SRC bash
+curl -sSL https://get.haskellstack.org/ | sh
+#+END_SRC
+
+Install **nix**:
+
+#+BEGIN_SRC bash
+curl https://nixos.org/nix/install | sh
+#+END_SRC
+
+** Programmation Fonctionnelle?
+*** Von Neumann Architecture (1945)
+
+#+BEGIN_SRC
+ +--------------------------------+
+ | +----------------------------+ |
+ | | central processing unit | |
+ | | +------------------------+ | |
+ | | | Control Unit | | |
++------+ | | +------------------------+ | | +--------+
+|input +---> | +------------------------+ | +--> output |
++------+ | | | Arithmetic/Logic Unit | | | +--------+
+ | | +------------------------+ | |
+ | +-------+---^----------------+ |
+ | | | |
+ | +-------v---+----------------+ |
+ | | Memory Unit | |
+ | +----------------------------+ |
+ +--------------------------------+
+#+END_SRC
+
+made with http://asciiflow.com
+
+*** Von Neumann vs Church
+
+- programmer à partir de la machine (Von Neumann)
+ + tire vers l'optimisation
+ + mots de bits, caches, détails de bas niveau
+ + actions séquentielles
+ + *1 siècle d'expérience*
+
+. . .
+
+- programmer comme manipulation de symbole (Alonzo Church)
+ + tire vers l'abstraction
+ + plus proche des représentations mathématiques
+ + ordre d'évaluation non imposé
+ + *4000 ans d'expérience*
+
+*** Histoire
+
+- λ-Calculus, Alonzo Church & Rosser 1936
+ - Foundation, explicit side effect no implicit state
+
+. . .
+
+- LISP (McCarthy 1960)
+ - Garbage collection, higher order functions, dynamic typing
+
+. . .
+
+- ML (1969-80)
+ - Static typing, Algebraic Datatypes, Pattern matching
+
+. . .
+
+- Miranda (1986) → Haskell (1992‥)
+ - Lazy evaluation, pure
+
+** Pourquoi Haskell?
+*** Simplicité par l'abstraction
+
+ *=/!\= SIMPLICITÉ ≠ FACILITÉ =/!\=*
+
+- mémoire (garbage collection)
+- ordre d'évaluation (non strict / lazy)
+- effets de bords (pur)
+- manipulation de code (referential transparency)
+
+. . .
+
+Simplicité: Probablement le meilleur indicateur de réussite de projet.
+
+*** Production Ready™
+
+- rapide
+ - équivalent à Java (~ x2 du C)
+ - parfois plus rapide que C
+ - bien plus rapide que python et ruby
+. . .
+- communauté solide
+ - 3k comptes sur Haskellers
+ - >30k sur reddit /(35k rust, 45k go, 50k nodejs, 4k ocaml, 13k clojure)/
+ - libs >12k sur hackage
+. . .
+- entreprises
+ - Facebook (fighting spam, HAXL, ...)
+ - beaucoup de startups, finance en général
+. . .
+- milieu académique
+ - fondations mathématiques
+ - fortes influences des chercheurs
+ - tire le langage vers le haut
+
+*** Tooling
+
+- compilateur (GHC)
+- gestion de projets ; cabal, stack, hpack, etc...
+- IDE / hlint ; rapidité des erreurs en cours de frappe
+- frameworks hors catégorie (servant, yesod)
+- ecosystèmes très matures et inovant
+ - Elm (⇒ frontend)
+ - Purescript (⇒ frontend)
+ - GHCJS (⇒ frontend)
+ - Idris (types dépendants)
+ - Hackett (typed LISP avec macros)
+ - Eta (⇒ JVM)
+
+*** Qualité
+
+#+BEGIN_QUOTE
+/Si ça compile alors il probable que ça marche/
+#+END_QUOTE
+. . .
+- tests unitaires :
+ chercher quelques erreurs manuellements
+. . .
+- /test génératifs/ :
+ chercher des erreurs sur beaucoups de cas générés aléatoirements
+ & aide pour trouver l'erreur sur l'objet le plus simple
+. . .
+- /finite state machine generative testing/ :
+ chercher des erreurs sur le déroulement des actions
+ entre différents agents indépendants
+. . .
+- *preuves*:
+ chercher des erreur sur *TOUTES* les entrées possibles
+ possible à l'aide du système de typage
+
+* Premiers Pas en Haskell
+*** DON'T PANIC
+
+#+BEGIN_SRC
+██████╗ ██████╗ ███╗ ██╗████████╗ ██████╗ █████╗ ███╗ ██╗██╗ ██████╗██╗
+██╔══██╗██╔═══██╗████╗ ██║╚══██╔══╝ ██╔══██╗██╔══██╗████╗ ██║██║██╔════╝██║
+██║ ██║██║ ██║██╔██╗ ██║ ██║ ██████╔╝███████║██╔██╗ ██║██║██║ ██║
+██║ ██║██║ ██║██║╚██╗██║ ██║ ██╔═══╝ ██╔══██║██║╚██╗██║██║██║ ╚═╝
+██████╔╝╚██████╔╝██║ ╚████║ ██║ ██║ ██║ ██║██║ ╚████║██║╚██████╗██╗
+╚═════╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝ ╚═════╝╚═╝
+#+END_SRC
+
+- Haskell peut être difficile à vraiment maîtriser
+- Trois languages en un:
+ - Fonctionnel
+ - Imperatif
+ - Types
+- Polymorphisme:
+ - contexte souvent semi-implicite change le comportement du code.
+
+*** Fichier de script isolé
+
+Avec Stack: https://haskellstack.org
+
+#+BEGIN_SRC haskell
+#!/usr/bin/env stack
+{- stack script
+ --resolver lts-12.10
+ --install-ghc
+ --package protolude
+-}
+#+END_SRC
+
+Avec Nix: https://nixos.org/nix/
+
+#+BEGIN_SRC shell
+#! /usr/bin/env nix-shell
+#! nix-shell -i runghc
+#! nix-shell -p "ghc.withPackages (ps: [ ps.protolude ])"
+#! nix-shell -I nixpkgs="https://github.com/NixOS/nixpkgs/archive/18.09-beta.tar.gz"
+#+END_SRC
+
+*** Hello World! (1/3)
+
+#+BEGIN_SRC haskell
+-- hello.hs
+main :: IO ()
+main = putStrLn "Hello World!"
+#+END_SRC
+
+#+BEGIN_SRC
+> chmod +x hello.hs
+> ./hello.hs
+Hello World!
+#+END_SRC
+
+#+BEGIN_SRC
+> stack ghc -- hello.hs
+> ./hello
+Hello World!
+#+END_SRC
+
+*** Hello World! (2/3)
+
+#+BEGIN_SRC haskell
+main :: IO ()
+main = putStrLn "Hello World!"
+#+END_SRC
+
+- ~::~ de type ;
+- le type de ~main~ est ~IO ()~.
+- ~=~ égalité (la vrai, on peut interchanger ce qu'il y a des deux cotés) ;
+- le type de ~putStrLn~ est ~String -> IO ()~ ;
+- application de fonction =f x= pas =f(x)=, pas de parenthèse nécessaire ;
+
+*** Hello World! (3/3)
+
+#+BEGIN_SRC haskell
+main :: IO ()
+main = putStrLn "Hello World!"
+#+END_SRC
+
+- Le type ~IO a~ signifie: C'est une description d'une procédure qui quand elle
+ est évaluée peut faire des actions d'IO qui retournera une valeur de type ~a~ ;
+- ~main~ est le nom du point d'entrée du programme ;
+- Haskell runtime va chercher pour ~main~ et l'exécute.
+
+** What is your name?
+*** What is your name? (1/2)
+
+#+BEGIN_SRC haskell
+main :: IO ()
+main = do
+ putStrLn "Hello! What is your name?"
+ name <- getLine
+ let output = "Nice to meet you, " ++ name ++ "!"
+ putStrLn output
+#+END_SRC
+
+. . .
+
+- l'indentation est importante !
+- ~do~ commence une syntaxe spéciale qui permet de séquencer des actions ~IO~ ;
+- le type de ~getLine~ est ~IO String~ ;
+- ~IO String~ signifie: Ceci est la description d'une procédure qui lorsqu'elle
+ est évaluée peut faire des actions IO et retourne une valeur de type ~String~.
+
+*** What is your name? (2/2)
+
+#+BEGIN_SRC haskell
+main :: IO ()
+main = do
+ putStrLn "Hello! What is your name?"
+ name <- getLine
+ let output = "Nice to meet you, " ++ name ++ "!"
+ putStrLn output
+#+END_SRC
+
+- le type de ~getLine~ est ~IO String~
+- le type de ~name~ est ~String~
+- ~<-~ est une syntaxe spéciale qui n'apparait que dans la notation ~do~
+- ~<-~ signifie: évalue la procédure et attache la valeur renvoyée dans le nom
+ à gauche de ~<-~
+- ~let = ~ signifie que ~name~ est interchangeable avec ~expr~ pour
+ le reste du bloc ~do~.
+- dans un bloc ~do~, ~let~ n'a pas besoin d'être accompagné par ~in~ à la fin.
+
+** Erreurs classiques
+*** Erreur classique #1
+
+#+BEGIN_SRC haskell
+main :: IO ()
+main = do
+ putStrLn "Hello! What is your name?"
+ let output = "Nice to meet you, " ++ getLine ++ "!"
+ putStrLn output
+#+END_SRC
+
+#+BEGIN_SRC
+/Users/yaesposi/.deft/pres-haskell/name.hs:6:40: warning: [-Wdeferred-type-errors]
+ • Couldn't match expected type ‘[Char]’
+ with actual type ‘IO String’
+ • In the first argument of ‘(++)’, namely ‘getLine’
+ In the second argument of ‘(++)’, namely ‘getLine ++ "!"’
+ In the expression: "Nice to meet you, " ++ getLine ++ "!"
+ |
+6 | let output = "Nice to meet you, " ++ getLine ++ "!"
+ | ^^^^^^^
+Ok, one module loaded.
+#+END_SRC
+
+*** Erreur classique #1
+
+- ~String~ est ~[Char]~
+- Haskell n'arrive pas à faire matcher le type ~String~ avec ~IO String~.
+- ~IO a~ et ~a~ sont différents
+
+*** Erreur classique #2
+
+#+BEGIN_SRC haskell
+main :: IO ()
+main = do
+ putStrLn "Hello! What is your name?"
+ name <- getLine
+ putStrLn "Nice to meet you, " ++ name ++ "!"
+#+END_SRC
+
+#+BEGIN_SRC
+/Users/yaesposi/.deft/pres-haskell/name.hs:7:3: warning: [-Wdeferred-type-errors]
+ • Couldn't match expected type ‘[Char]’ with actual type ‘IO ()’
+ • In the first argument of ‘(++)’, namely
+ ‘putStrLn "Nice to meet you, "’
+ In a stmt of a 'do' block:
+ putStrLn "Nice to meet you, " ++ name ++ "!"
+ In the expression:
+ do putStrLn "Hello! What is your name?"
+ name <- getLine
+ putStrLn "Nice to meet you, " ++ name ++ "!"
+ |
+7 | putStrLn "Nice to meet you, " ++ name ++ "!"
+#+END_SRC
+
+*** Erreur classique #2 (fix)
+
+- Des parenthèses sont nécessaires
+- L'application de fonction se fait de gauche à droite
+
+#+BEGIN_SRC haskell
+main :: IO ()
+main = do
+ putStrLn "Hello! What is your name?"
+ name <- getLine
+ putStrLn ("Nice to meet you, " ++ name ++ "!")
+#+END_SRC
+
+* Concepts avec exemples
+*** Concepts
+- /style déclaratif & récursif/
+- /immutabilité/
+- /pureté/ (par défaut)
+- /evaluation paraisseuse/ (par défaut)
+- /ADT & typage polymorphique/
+
+*** /Style déclaratif & récursif/
+
+#+BEGIN_SRC python
+>>> x=0
+... for i in range(1,11):
+... tmp = i*i
+... if tmp%2 == 0:
+... x += tmp
+>>> x
+220
+#+END_SRC
+
+#+BEGIN_SRC haskell
+-- (.) composition (de droite à gauche)
+Prelude> sum . filter even . map (^2) $ [1..10]
+220
+Prelude> :set -XNoImplicitPrelude
+Prelude> import Protolude
+-- (&) flipped fn application (de gauche à droite)
+Protolude> [1..10] & map (^2) & filter even & sum
+220
+#+END_SRC
+
+*** /Style déclaratif & récursif/
+
+#+BEGIN_SRC python
+>>> x=0
+... for i in range(1,11):
+... j = i*3
+... tmp = j*j
+... if tmp%2 == 0:
+... x += tmp
+#+END_SRC
+
+#+BEGIN_SRC haskell
+Prelude> sum . filter even . map (^2) . map (*3) $ [1..10]
+Protolude> [1..10] & map (*3) & map (^2) & filter even & sum
+#+END_SRC
+
+*** /Style déclaratif & récursif/
+
+- Contrairement aux languages impératifs la récursion n'est généralement pas chère.
+- tail recursive function, mais aussi à l'aide de la lazyness
+
+*** /Imutabilité/
+
+#+BEGIN_SRC haskell
+-- | explicit recursivity
+incrementAllEvenNumbers :: [Int] -> [Int]
+incrementAllEvenNumbers (x:xs) = y:incrementAllEvenNumbers xs
+ where y = if even x then x+1 else x
+
+-- | better with use of higher order functions
+incrementAllEvenNumbers' :: [Int] -> [Int]
+incrementAllEvenNumbers' ls = map incrementIfEven ls
+ where
+ incrementIfEven :: Int -> Int
+ incrementIfEven x = if even x then x+1 else x
+#+END_SRC
+
+*** /Pureté/: Function vs Procedure/Subroutines
+
+- Une /fonction/ n'a pas d'effet de bord
+- Une /Procedure/ ou /subroutine/ but engendrer des effets de bords lors de son
+ évaluation
+
+*** /Pureté/: Function vs Procedure/Subroutines (exemple)
+
+#+BEGIN_SRC haskell
+dist :: Double -> Double -> Double
+dist x y = sqrt (x**2 + y**2)
+#+END_SRC
+
+
+#+BEGIN_SRC haskell
+getName :: IO String
+getName = readLine
+#+END_SRC
+
+- *IO a* ⇒ *IMPUR* ; effets de bords hors evaluation :
+ - lire un fichier ;
+ - écrire sur le terminal ;
+ - changer la valeur d'une variable en RAM est impur.
+
+*** /Pureté/: Gain, paralellisation gratuite
+
+#+BEGIN_SRC haskell
+import Foreign.Lib (f)
+-- f :: Int -> Int
+-- f = ???
+
+foo = sum results
+ where results = map f [1..100]
+#+END_SRC
+
+. . .
+
+*~pmap~ FTW!!!!! Assurance d'avoir le même résultat avec 32 cœurs*
+
+#+BEGIN_SRC haskell
+import Foreign.Lib (f)
+-- f :: Int -> Int
+-- f = ???
+
+foo = sum results
+ where results = pmap f [1..100]
+#+END_SRC
+
+*** /Pureté/: Structures de données immuable
+
+Purely functional data structures,
+/Chris Okasaki/
+
+Thèse en 1996, et un livre.
+
+Opérations sur les listes, tableaux, arbres
+de complexité amortie equivalent ou proche
+(pire des cas facteur log(n))
+de celle des structures de données muables.
+
+*** /Évaluation parraisseuse/: Stratégies d'évaluations
+
+=(h (f a) (g b))= peut s'évaluer:
+
+- =a= → =(f a)= → =b= → =(g b)= → =(h (f a) (g b))=
+- =b= → =a= → =(g b)= → =(f a)= → =(h (f a) (g b))=
+- =a= et =b= en parallèle puis =(f a)= et =(g b)= en parallèle et finallement
+ =(h (f a) (g b))=
+- =h= → =(f a)= seulement si nécessaire et puis =(g b)= seulement si nécessaire
+
+Par exemple: =(def h (λx.λy.(+ x x)))= il n'est pas nécessaire d'évaluer =y=,
+dans notre cas =(g b)=
+
+*** /Évaluation parraisseuse/: Exemple
+
+#+BEGIN_SRC haskell
+quickSort [] = []
+quickSort (x:xs) = quickSort (filter (=x) xs)
+
+minimum list = head (quickSort list)
+#+END_SRC
+
+Un appel à ~minimum longList~ ne vas pas ordonner toute la liste.
+Le travail s'arrêtera dès que le premier élément de la liste ordonnée sera trouvé.
+
+~take k (quickSort list)~ est en ~O(n + k log k)~ où ~n = length list~.
+Alors qu'avec une évaluation stricte: ~O(n log n)~.
+
+*** /Évaluation parraisseuse/: Structures de données infinies (zip)
+
+#+BEGIN_SRC haskell
+zip :: [a] -> [b] -> [(a,b)]
+zip [] _ = []
+zip _ [] = []
+zip (x:xs) (y:ys) = (x,y):zip xs ys
+#+END_SRC
+
+#+BEGIN_SRC haskell
+zip [1..] ['a','b','c']
+#+END_SRC
+
+s'arrête et renvoie :
+
+#+BEGIN_SRC haskell
+[(1,'a'), (2,'b'), (3, 'c')]
+#+END_SRC
+
+*** /Évaluation parraisseuse/: Structures de données infinies (2)
+
+#+BEGIN_SRC haskell
+Prelude> zipWith (+) [0,1,2,3] [10,100,1000]
+[10,101,1002]
+Prelude> take 3 [1,2,3,4,5,6,7,8,9]
+[1,2,3]
+#+END_SRC
+
+#+BEGIN_SRC haskell
+Prelude> fib = 0:1:(zipWith (+) fib (tail fib))
+Prelude> take 10 fib
+[0,1,1,2,3,5,8,13,21,34]
+#+END_SRC
+
+*** /ADT & Typage polymorphique/
+
+Algebraic Data Types.
+
+#+BEGIN_SRC haskell
+data Void = Void Void -- 0 valeur possible!
+data Unit = () -- 1 seule valeur possible
+
+data Product x y = P x y
+data Sum x y = S1 x | S2 y
+#+END_SRC
+
+Soit ~#x~ le nombre de valeurs possibles pour le type ~x~
+alors:
+
+- ~#(Product x y) = #x * #y~
+- ~#(Sum x y) = #x + #y~
+
+*** /ADT & Typage polymorphique/: Inférence de type
+
+À partir de :
+
+#+BEGIN_SRC haskell
+zip [] _ = []
+zip _ [] = []
+zip (x:xs) (y:ys) = (x,y):zip xs ys
+#+END_SRC
+
+le compilateur peut déduire:
+
+#+BEGIN_SRC haskell
+zip :: [a] -> [b] -> [(a,b)]
+#+END_SRC
+
+** Composabilité
+*** Composabilité vs Modularité
+
+Modularité: soit un ~a~ et un ~b~, je peux faire un ~c~.
+ ex: x un graphique, y une barre de menu => une page
+ ~let page = mkPage ( graphique, menu )~
+
+Composabilité: soit deux ~a~ je peux faire un autre ~a~.
+ ex: x un widget, y un widget => un widget
+ ~let page = x <+> y~
+
+Gain d'abstraction, moindre coût.
+
+*Hypothèses fortes sur les ~a~*
+
+*** Exemples
+
+- *Semi-groupes* 〈+〉
+- *Monoides* 〈0,+〉
+
+- *Catégories* 〈obj(C),hom(C),∘〉
+- Foncteurs ~fmap~ (~(<$>)~)
+- Foncteurs Applicatifs ~ap~ (~(<*>)~)
+- Monades ~join~
+- Traversables ~map~
+- Foldables ~reduce~
+
+* Catégories de bugs évités avec Haskell
+
+*** Real Productions Bugs™
+
+Bug vu des dizaines de fois en prod malgré:
+
+ 1. specifications fonctionnelles
+ 2. spécifications techniques
+ 3. tests unitaires
+ 4. 3 envs, dev, recette/staging/pre-prod, prod
+ 5. Équipe de QA qui teste en recette
+
+Solutions simples.
+
+*** **Null Pointer Exception**: Erreur classique (1)
+
+Au début du projet :
+
+#+BEGIN_SRC javascript
+int foo( x ) {
+ return x + 1;
+}
+#+END_SRC
+
+*** **Null Pointer Exception**: Erreur classique (2)
+
+Après quelques semaines/mois/années :
+
+#+BEGIN_SRC javascript
+import do_shit_1 from "foreign-module";
+int foo( x ) {
+ ...
+ var y = do_shit_1(x);
+ ...
+ return do_shit_20(y)
+}
+...
+var val = foo(26/2334 - Math.sqrt(2));
+#+END_SRC
+
+. . .
+
+#+BEGIN_SRC
+███████ █████ ███ ███ ███ ███ ███ ███ ███ ███ ███
+███ ██ ███ ███ ███ ███ ████ ████ ███ ███ ███ ███ ███
+███ ██ ███ ███ ███ ███ █████ █████ ███ ███ ███ ███ ███
+███████ ███ ███ ███ ███ ███ █████ ███ ███ ███ ███ ███ ███
+███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███
+███ ███ ███ ███ ███ ███ ███ █ ███ █ █ █ █ █
+███ ███ ███ ███ ███ ███ ███ ███
+███████ █████ █████ ███ ███ ███ ███ ███ ███ ███
+#+END_SRC
+
+| *Null Pointer Exception*
+
+*** Null Pointer Exception: Data type ~Maybe~
+
+#+BEGIN_SRC haskell
+data Maybe a = Just a | Nothing
+...
+foo :: Maybe a
+...
+myFunc x = let t = foo x in
+ case t of
+ Just someValue -> doThingsWith someValue
+ Nothing -> doThingWhenNothingIsReturned
+#+END_SRC
+
+Le compilateur oblige à tenir compte des cas particuliers!
+Impossible d'oublier.
+
+*** Null Pointer Exception: Etat
+
+- Rendre impossibe de fabriquer un état qui devrait être impossible d'avoir.
+- Pour aller plus loin voir, FRP, CQRS/ES, Elm-architecture, etc...
+
+*** Erreur due à une typo
+
+#+BEGIN_SRC haskell
+data Foo x = LongNameWithPossibleError x
+...
+foo (LongNameWithPosibleError x) = ...
+#+END_SRC
+
+*Erreur à la compilation*:
+Le nom d'un champ n'est pas une string
+(voir les objets JSON).
+
+*** Echange de parameters
+
+#+BEGIN_SRC haskell
+data Personne = Personne { uid :: Int, age :: Int }
+foo :: Int -> Int -> Personne -- ??? uid ou age?
+#+END_SRC
+
+#+BEGIN_SRC haskell
+newtype UID = UID Int deriving (Eq)
+data Personne = Personne { uid :: UID, age :: Int }
+foo :: UDI -> Int -> Personne -- Impossible de confondre
+#+END_SRC
+
+*** Changement intempestif d'un Etat Global
+
+#+BEGIN_SRC haskell
+foo :: GlobalState -> x
+#+END_SRC
+
+*~foo~ ne peut pas changer =GlobalState=*
+
+* Organisation du Code
+*** Grands Concepts
+
+Procedure vs Functions:
+
+| Gestion d'une configuration globale |
+| Gestion d'un état global |
+| Gestion des Erreurs |
+| Gestion des IO |
+
+*** Monades
+
+Pour chacun de ces /problèmes/ il existe une monade:
+
+| Gestion d'une configuration globale | ~Reader~ |
+| Gestion d'un état global | ~State~ |
+| Gestion des Erreurs | ~Either~ |
+| Gestion des IO | ~IO~ |
+
+*** Effets
+
+Gestion de plusieurs Effets dans la même fonction:
+
+- MTL
+- Free Monad
+- Freer Monad
+
+Idée: donner à certaines sous-fonction accès à une partie des effets seulement.
+
+Par exemple:
+- limiter une fonction à la lecture de la DB mais pas l'écriture.
+- limiter l'écriture à une seule table
+- interdire l'écriture de logs
+- interdire l'écriture sur le disque dur
+- etc...
+
+*** Exemple dans un code réel (1)
+
+#+BEGIN_SRC haskell
+-- | ConsumerBot type, the main monad in which the bot code is written with.
+-- Provide config, state, logs and IO
+type ConsumerBot m a =
+ ( MonadState ConsumerState m
+ , MonadReader ConsumerConf m
+ , MonadLog (WithSeverity Doc) m
+ , MonadBaseControl IO m
+ , MonadSleep m
+ , MonadPubSub m
+ , MonadIO m
+ ) => m a
+#+END_SRC
+
+*** Exemple dans un code réel (2)
+
+#+BEGIN_SRC haskell
+bot :: Manager
+ -> RotatingLog
+ -> Chan RedditComment
+ -> TVar RedbotConfs
+ -> Severity
+ -> IO ()
+bot manager rotLog pubsub redbots minSeverity = do
+ TC.setDefaultPersist TC.filePersist
+ let conf = ConsumerConf
+ { rhconf = RedditHttpConf { _connMgr = manager }
+ , commentStream = pubsub
+ }
+ void $ autobot
+ & flip runReaderT conf
+ & flip runStateT (initState redbots)
+ & flip runLoggingT (renderLog minSeverity rotLog)
+#+END_SRC
+
+
+** Règles *pragmatiques*
+
+*** Organisation en fonction de la complexité
+
+#+BEGIN_QUOTE
+Make it work, make it right, make it fast
+#+END_QUOTE
+
+- Simple: directement IO (YOLO!)
+- Medium: Haskell Design Patterns: The Handle Pattern:
+ https://jaspervdj.be/posts/2018-03-08-handle-pattern.html
+- Medium (bis): MTL / Free / Freeer / Effects...
+- Gros: Three Layer Haskell Cake:
+ http://www.parsonsmatt.org/2018/03/22/three_layer_haskell_cake.html
+ + Layer 1: Imperatif
+ + Orienté Objet (Level 2 / 2')
+ + Fonctionnel
+
+*** 3 couches
+
+- *Imperatif*:
+ ReaderT IO
+ + Insérer l'état dans une ~TVar~, ~MVar~ ou ~IORef~ (concurrence)
+- *Orienté Objet*:
+ + Handle / MTL / Free...
+ + donner des access ~UserDB~, ~AccessTime~, ~APIHTTP~...
+- *Fonctionnel*: Business Logic ~f : Handlers -> Inputs -> Command~
+
+*** Services / Lib
+
+Service: ~init~ / ~start~ / ~close~ + methodes...
+Lib: methodes sans état interne.
+
+* Conclusion
+*** Pourquoi Haskell?
+
+- avantage compétitif: qualité & productivité hors norme
+- change son approche de la programmation
+- les concepts appris sont utilisables dans tous les languages
+- permet d'aller là où aucun autre langage ne peut vous amener
+- Approfondissement sans fin:
+ - Théorie: théorie des catégories, théorie des types homotopiques, etc...
+ - Optim: compilateur
+ - Qualité: tests, preuves
+ - Organisation: capacité de contraindre de très haut vers très bas
+
+*** Avantage compétitif
+
+- France, Europe du sud & Functional Programming
+- Coût Maintenance >> production d'un nouveau produit
+- Coût de la refactorisation
+- "Make it work, Make it right, Make it fast" moins cher.
+
+*** Pour la suite
+
+A chacun de choisir, livres, tutoriels, videos, chat, etc...
+
+- Voici une liste de resources : https://www.haskell.org/documentation
+- Mon tuto rapide : [[http://yannesposito.com/Scratch/en/blog/Haskell-the-Hard-Way/][Haskell the Hard Way]]
+- Moteurs de recherche par type : [[http://hayoo.fh-wedel.de][hayoo]] & [[http://haskell.org/hoogle][hoogle]]
+- Communauté & News : http://haskell.org/news & ~#haskell-fr~ sur freenode
+- Libs: https://hackage.haskell.org & https://stackage.org
+
+* Appendix
+*** STM: Exemple (Concurrence) (1/2)
+
+#+BEGIN_SRC java
+class Account {
+ float balance;
+ synchronized void deposit(float amount){
+ balance += amount; }
+ synchronized void withdraw(float amount){
+ if (balance < amount) throw new OutOfMoneyError();
+ balance -= amount; }
+ synchronized void transfert(Account other, float amount){
+ other.withdraw(amount);
+ this.deposit(amount); }
+}
+#+END_SRC
+
+Situation d'interblocage typique. (A transfert vers B et B vers A).
+
+*** STM: Exemple (Concurrence) (2/2)
+
+#+BEGIN_SRC haskell
+deposit :: TVar Int -> Int -> STM ()
+deposit acc n = do
+ bal <- readTVar acc
+ writeTVar acc (bal + n)
+withdraw :: TVar Int -> Int -> STM ()
+withdraw acc n = do
+ bal <- readTVar acc
+ if bal < n then retry
+ writeTVar acc (bal - n)
+transfer :: TVar Int -> TVar Int -> Int -> STM ()
+transfer from to n = do
+ withdraw from n
+ deposit to n
+#+END_SRC
+
+- pas de lock explicite, composition naturelle dans ~transfer~.
+- si une des deux opération échoue toute la transaction échoue
+- le système de type force cette opération a être atomique:
+ ~atomically :: STM a -> IO a~