Tuples
- une structure de données très simple
- paquet d’un nombre fixe de données manipulées comme un tout
- l’ordre dans lequel on place les données est important
Différences avec les tableaux
- ils peuvent contenir des données de types différents
- ils sont immutables
La syntaxe est de séparer les types par des virgules, le tout dans une parenthèse.
La taille d'un tuple est contrainte par son type
Il est possible de déclarer des val/var
contenant des tuples
Accéder aux composantes
On utilise la syntaxe ._i
Notation des indices
Les indices démarrent à 1 et non 0. Donc le premier élément est à l’indice 1.
Pattern-matching
Syntaxe :
Motif valide de tuple
- La bonne taille : autant de composantes que le tuple
expr
sinon, erreur de compilation!- motifs des composantes : doivent représenter des valeurs du bon type
Immutabilité des tuples
On ne peut pas modifier les composantes d’un tuple
On peut insérer un tuple dans une var
(mais pas dans une val
car immutable)
Même dans une
var
, un tuple reste immutable
Nouveaux motifs pour le pattern-matching
Le pattern-matching inspecte la valeur d’une expression mais surtout sa structure, sa “forme”.
De nouveaux motifs peuvent être utilisés pour le patter-matching :
- tuples
- imbriqués
- variables
- pour les types algébriques
Motif variable
Motif universel ⇒ il correspond à n’importe quoi du bon type, comme _
, mais il permet de nommer ce n’importe quoi (→ plus joli que ._1
par exemple)
Syntaxe : identifiant quelconque, commençant par une minuscule
L’identifiant choisi (nom
dans l’exemple) devient une val
:
- qui n’est utilisable que dans la branche du motif
- et dont la valeur n’est déterminée qu’à l’exécution.
Le motif variable peut masquer une
val
déclarée plus hautLa portée de la variable
ok
dans lematch
est locale à la branche, et est donc prioritaire
Motifs imbriqués
⇒ Permet de gagner en concision, un seul motif exprime alors plusieurs critères en même temps
Cela permet d’analyser la structure d’une valeur de façon “profonde” en imbriquant les motifs.
Types algébriques
Les tuples :
- utiles pour regrouper plusieurs données en une seule
type
alias pour les tuples : améliore la lisibilité
Alias de type
Un alias est juste un autre nom, pas un nouveau type
Limitations des tuples
- Accès aux composantes
._i
: sujet à erreur (par exemple date en FR et ENG) ⇒ solution (partielle) → le pattern-matching et les motifs variables- Type sans alternatives : taille fixe ⇒ un -tuple aura toujours composantes
Les types algébriques permettent de
- définir un nouveau type de données, composite
- nommer les composantes du type
- autoriser les alternatives
case class
Par exemple pour modéliser une date par un jour, un mois et une année
Déclaration de type :
Création de valeurs :
Notes sur
case clas
Pas de mot-clef
new
, la valeur est uniquement définie par le nom du constructeur et la valeur des composantesDate
est le nom du type et du constructeur
Pour accéder aux composantes, on utilise leur nom (notation pointée) :
Les case class
sont immutables, on doit donc renvoyer de nouvelles valeurs
Pour le pattern-matching, Date
peut aussi être un motif :
sealed trait
et extends
Une image peut être :
- soit un rectangle : défini par sa longueur et sa largeur
- soit un cercle : défini par son rayon
- soit plus compliquée : celle contenue dans un fichier
⇒ Création de type qui réunissent des types créés avec case class
Nommage du nouveau type par sealed trait Type
On autorise des alternatives par extends
⇒ ici 3 variantes pour le type Image
Le mot-clé sealed
: ces variantes (les case class
de ce fichier) sont les seules possibles.
==On peut donc créer des types de tailles diverses et hétérogènes dans leurs types==
On a le choix pour le type déclaré ⇒ cela détermine la validité des accès aux composantes.
Le type de la variante, ici Rectangle
, est plus précis. Souvent, en programmation, il vaut mieux, quand c’est possible, réfléchir de manière générale, sur le type algébrique global, ici Image
.
Les types algébriques simples sont immutables ⇒ composés de case class
Pattern-matching :
- motifs des constructeurs: traiter tous les cas possibles
- motifs des composantes: accéder à leur contenu
Le type Scala Option[T]
On souhaite calculer l’aire d’une image, on peut pour un cercle, pour un rectangle, mais pas pour un fichier (d’après les case class
définis précédemment)
On peut définir un nouveau type algébrique représentant qu’un résultat n’existe pas toujours :
Remarque
Une
case class
sans composante se notecase object
Puis on peut utiliser ce type pour définir notre fonction :
Un type prédéfini joue le rôle du type Result
: le type Option[T]
où T
est un type quelconque (Double
dans l’exemple) avec 2 alternatives :
Some
: 1 composante de typeT
None
: pas de composante.
Bilan
Types de données composites :
- tuples et types algébriques
- modéliser des données composites, agrégeant plusieurs informations
Pattern-matching :
- motif tuples, variables, imbriqués, et constructeur
- motifs: contraintes sur les valeurs possibles
- moyen d’accéder au contenu effectif des composantes de la valeur composite