Jeroen Engels (Yeuroune)
age : Int
age = 29
nom : String
nom = "Jeroen Engels"Dynamique : Vérification au cours de l'exécution (JavaScript, Python, Clojure, ...)
# Python
>>> "string" + 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objectsStatique : Vérifiés avant l'exécution
(Elm, Java, Haskell, ...)
maFonction : TypeParametre1 -> TypeParametre2 -> TypeDeRetour
maFonction parametre1 parametre2 =
    valeurDeLaFonction
variable : Type
variable =
  maFonction argument1 argument2
type alias Prenom = String
type alias Nom =
  { prenom : Prenom
  , age : Int
  }
type Sexe
  = Homme
  | Femme
  | Autre Stringquantite : String
quantite = 100 -- NON!prenom : String -- Garantie par le compilateur
prenom =
  "Jeroen"
  
-- Si jamais on change
prenom : String
prenom =
  1000 -- Erreur de compilation
  
a : (Username -> Username) -> User -> User
a b c =
  d (b (e c)) caddition : number -> number -> number
nomUtilisateur : User -> String
modifiePrenom : (Username -> Username) -> User -> Usertype alias RequeteAuServeur data =
  { enCours : Bool
  , enErreur : Bool
  , données : Maybe data
  }maRequete : RequeteAuServeur String
maRequete =
  { enCours = True
  , enErreur = True
  , données = Just "Jeroen"
  }type RequeteAuServeur data
  = NonDemarree
  | EnCours
  | EnErreur
  | EnSucces datapar Richard Feldman
type alias User =
  { nom : String
  -- "admin" ou "user"
  , role : String
  }
peutSupprimerBaseDeDonnees : User -> Bool
peutSupprimerBaseDeDonnees user =
    if user.role == "user" then
        False
    else
        True
user : User
user =
  { nom = "Jeroen Engels"
  , role = "User"
  }type alias User =
  { nom : String
  , role : Role
  }
type Role
  = Admin
  | User
peutSupprimerBaseDeDonnees : User -> Bool
peutSupprimerBaseDeDonnees user =
    case user.role of
    	Admin -> True
    	User -> Falsetype alias User =
  { idUser : String
  , idVoiture : String
  }
nouvelleVoiture : String -> User -> User
nouvelleVoiture idVoiture user =
  { user | idUser = idVoiture }
type alias User =
  { idUser : UserId
  , idVoiture : VoitureId
  }
type UserId
  = UserId String
type VoitureId
  = VoitureId String
nouvelleVoiture : VoitureId -> User -> User
nouvelleVoiture idVoiture user =
  { user | idUser = idVoiture } -- Erreur
type alias User =
  { nom : String
  , motDePasse : String
  }
modifieMotDePasse : String -> User -> User
modifieMotDePasse motDePasse user =
  { user | motDePasse = motDePasse }
utilisateurAvecMotDePasse =
  modifieMotDePasse "a" utilisateurtype alias User =
  { nom : String
  , motDePasse : MotDePasseFort
  }
type MotDePasseFort
  = MotDePasseFort String
modifieMotDePasse : MotDePasseFort -> User -> User
modifieMotDePasse motDePasse user =
  { user | motDePasse = motDePasse }
utilisateurAvecMotDePasse =
  modifieMotDePasse (MotDePasseFort "a") utilisateurmodule MotDePasseFort exposing
  (MotDePasseFort, fromString, comparerMotDePasse, hash)
-- Ne pas faire MotDePasseFort(..)
type MotDePasseFort
  = MotDePasseFort String
  
{-| Si mdp est fort, alors retourne Just mdp, sinon Nothing -}
fromString : String -> Maybe MotDePasseFort
comparerMotDePasse : String -> MotDePasseFort -> Bool
hash : MotDePasseFort -> Stringtype alias User =
  { nom : String
  , motDePasse : MotDePasseFort
  }
modifieMotDePasse : MotDePasseFort -> User -> User
modifieMotDePasse motDePasse user =
  { user | motDePasse = motDePasse }
utilisateurAvecMotDePasse =
  case MotDePasseFort.fromString "a" of
    Just mdp -> 
      modifieMotDePasse mdp utilisateur
    Nothing -> 
      utilisateurLimite les opérations possibles sur un type
Cacher l'implémentation (encapsulation)
Opaque par défaut
type Never
  = JustOneMore Nevertype Never
  = JustOneMore Never
  
a : Never
a =
  JustOneMore (JustOneMore (JustOneMore (...
staticHtml : List (Html Never) -> Html Nevertype RequeteAuServeur data
  = NonDemarree
  | EnChargement
  | EnErreur
  | EnSucces data
  
reponse : RequeteAuServeur String
reponseAvecUtilisateur : RequeteAuServeur User-- a n'est pas utilisé
type Fantome a
  = Fantome QuelqueChosetype Id data
  = Id String
type Voiture = ...
type alias User =
  { voitureId : Id Voiture
  }type Monnaie monnaie
  = Monnaie Int
addition : Monnaie m -> Monnaie m -> Monnaie m
euros : Monnaie Euros
euros = Monnaie 1000
dollars : Monnaie Dollars
dollars = Monnaie 100
somme = addition euros dollars -- Erreur!type Button msg =
  Button
    { label : String
    , onClick : msg
    -- ...
    }
    
withOnClick : msg -> Button msg -> Button msg
------------------------------------------------
view : Html Msg
view =
  Button.new
    |> Button.withLabel "Clickez-moi!"
    |> Button.withOnClick ButtonHasBeenClicked
    |> Button.toHtmlview : Html Msg
view =
  Button.new
    |> Button.withLabel "Clickez-moi!"
    -- On ne veut pas un bouton désactivé cliquable!
    |> Button.withOnClick ButtonHasBeenClicked
    |> Button.disabled
    |> Button.toHtmltype Button etat msg =
  Button { ... }
new : Button { clickOrDisabled : () } msg
withOnClick :
  msg
  -> Button { etat | clickOrDisabled : () } msg
  -> Button etat msg
disabled :
  Button { etat | clickOrDisabled : () } msg
  -> Button etat msgview : Html Msg
view =
  Button.new
    |> Button.withLabel "Clickez-moi!"
    |> Button.withOnClick ButtonHasBeenClicked
    -- Erreur du compilateur
    -- "Il manque le champ `clickOrDisabled`"
    |> Button.disabled
    |> Button.toHtmlJeroen Engels (Yeuroune)
jfmengels sur le Slack Elm