Les génériques sont une fonctionnalité du langage qui permet de réutiliser du code.
Par exemple, le type des éléments d'un tableau ne devrait pas avoir d'importance pour en calculer la longueur.
C'est pourquoi la fonction length utilise un paramètre de type générique a dans sa signature de type.
length : List a -> Int
Quand un type est générique par rapport à un autre type, on écrit le nom de cet autre type en minuscules et on l'appelle un paramètre de type.
Les exemples les plus courants sont les types personnalisés List, Maybe et Result.
-- Maybe is generic over the type a
type Maybe a
= Nothing
| Just a
someString : Maybe String
someString = Just "hello"
someInt : Maybe Int
someInt = Just 42
Une remarque importante à propos des noms de paramètres de type, c'est qu'ils peuvent comporter plusieurs caractères. La seule contrainte est qu'il s'agit de noms en minuscules. C'est pourquoi, quand c'est utile, on a tendance à leur donner des noms explicites.
Un type peut être générique par rapport à plusieurs autres types, et donc avoir plusieurs paramètres de type. Dans ce cas, chaque type indépendant reçoit un nom en minuscules différent. Le fait d'être indépendants ne les empêche pas de devenir le même type, cela leur permet simplement d'être différents.
-- Result is generic over the types error and value
type Result error value
= Ok value
| Err error
Les alias de type enregistrement peuvent aussi avoir des paramètres de type, même si c'est moins courant.
-- Event is generic over the type a
type alias Event a =
{ at : Time
, data : a
}
Puisque les types peuvent être génériques, les fonctions peuvent l'être aussi.
On peut écrire des fonctions qui manipulent des types génériques, comme Maybe.withDefault.
withDefault : a -> Maybe a -> a
withDefault default maybe =
case maybe of
Just value -> value
Nothing -> default
Les fonctions qui prennent d'autres fonctions en paramètres sont appelées des fonctions d'ordre supérieur, et celles-ci peuvent aussi être génériques.
map : (a -> b) -> Maybe a -> Maybe b
map function maybe =
case maybe of
Just value ->
Just (function value)
Nothing ->
Nothing
Dans cet exercice, tu vas écrire un coffre au trésor générique (et magique !) pour y ranger quelques trésors.
Définis un type personnalisé TreasureChest avec une seule variante.
Cette variante doit avoir une valeur String associée, qui servira à stocker le mot de passe du coffre au trésor.
La variante doit aussi avoir une valeur générique associée, qui servira à stocker le trésor. Cette valeur est générique pour que le trésor puisse être n'importe quoi.
Cette fonction prend deux paramètres
String (pour essayer un mot de passe)TreasureChest
Cette fonction doit vérifier la tentative de mot de passe fournie par rapport à la String contenue dans le TreasureChest.
La fonction renvoie un Maybe.
Si les mots de passe correspondent, renvoie Just avec la valeur générique du TreasureChest (le trésor !)
Si les mots de passe ne correspondent pas, renvoie Nothing.
Cette fonction (d'ordre supérieur) prend deux paramètres
TreasureChest, également avec le même type génériqueCette fonction doit appeler la fonction de multiplication avec le trésor qui se trouve dans le coffre.
La fonction renvoie un nouveau TreasureChest, avec le même mot de passe que l'original et avec le trésor multiplié (la valeur de retour)
Inscris-toi sur Exercism pour apprendre et maîtriser Elm avec 28 concepts110 exercices, et un vrai mentorat humain, le tout gratuitement.