Foncteurs et mappeurs génériques
Écrire des fonctions map génériques pour tout conteneur.
Foncteurs et mappeurs génériques est une leçon TypeScript Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage TypeScript Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours TypeScript Academy comprend 4 leçons au total.
Un Functor générique
Nous utilisons maintenant l'encodage pour son objectif : un map générique qui fonctionne sur tout conteneur enregistré. L'interface Functor, paramétrée par un URI, déclare une seule méthode.
interface Functor<F extends URIS> {
readonly URI: F;
map<A, B>(fa: Kind<F, A>, f: (a: A) => B): Kind<F, B>;
}L'instance de tableau
Une instance implémente map pour un URI. L'instance de tableau applique map au moyen de la méthode intégrée des tableaux. Son Kind<"Array", A> se résout en A[].
const arrayFunctor: Functor<"Array"> = {
URI: "Array",
map: (fa, f) => fa.map(f)
};Utiliser l'instance de tableau
Appeler map sur l'instance de tableau transforme chaque élément tout en préservant le type de conteneur tableau.
const doubled = arrayFunctor.map([1, 2, 3], n => n * 2);
// doubled: number[] -> [2, 4, 6]Le type option
Définissez une option comme une valeur ou null, puis enregistrez-la. Son map applique la fonction uniquement lorsqu'une valeur est présente ; sinon, il propage null.
interface URItoKind<A> { Option: A | null }
type Option<A> = A | null;L'instance d'option
L'instance d'option préserve le conteneur d'option : une fonction est appliquée à la valeur, tandis que null reste null.
const optionFunctor: Functor<"Option"> = {
URI: "Option",
map: (fa, f) => (fa === null ? null : f(fa))
};Utiliser l'instance d'option
La même structure de map fonctionne désormais sur un conteneur complètement différent. Les valeurs présentes sont transformées ; les valeurs absentes restent inchangées.
const a = optionFunctor.map(5, n => n + 1); // 6
const b = optionFunctor.map(null, n => n + 1); // nullUne abstraction, de nombreux conteneurs
C'est là tout l'intérêt. arrayFunctor et optionFunctor partagent la même interface Functor. Le code écrit avec Functor<F> fonctionne pour les deux sans modification.
function bumpAll<F extends URIS>(
F: Functor<F>,
fa: Kind<F, number>
): Kind<F, number> {
return F.map(fa, n => n + 1);
}Appeler la fonction générique
bumpAll ne sait pas et n'a pas besoin de savoir quel conteneur il reçoit. Transmettez l'instance et les données ; le résultat préserve le type du conteneur.
const arr = bumpAll(arrayFunctor, [1, 2]); // number[] -> [2, 3]
const opt = bumpAll(optionFunctor, 9); // number | null -> 10Lois de Functor
Un foncteur correct respecte deux lois : appliquer la fonction identité ne change rien, et appliquer deux fonctions successivement équivaut à appliquer leur composition. Les instances de tableau et d'option ci-dessus respectent toutes deux ces lois.
// map(fa, x => x) === fa
// map(map(fa, f), g) === map(fa, x => g(f(x)))Ajouter d'autres instances
Comme l'abstraction est ouverte, de nouveaux conteneurs peuvent être intégrés en enregistrant un URI et en fournissant une instance. Un arbre, un résultat ou une tâche devient ainsi compatible avec map grâce au même code générique.
// Register URI, implement Functor<"Tree">,
// and bumpAll works on trees too - no edits to bumpAllPourquoi c'est important
Les foncteurs génériques sont la porte d'entrée vers les abstractions fonctionnelles dans TypeScript : les applicatifs, les monades et les parcours. Chacune est une interface sur Kind<F, A>, avec des instances pour chaque conteneur. Vous comprenez maintenant le mécanisme qui rend fp-ts et Effect possibles.
interface Monad<F extends URIS> extends Functor<F> {
of<A>(a: A): Kind<F, A>;
chain<A, B>(fa: Kind<F, A>, f: (a: A) => Kind<F, B>): Kind<F, B>;
}Vérification rapide
Vérifiez votre compréhension des foncteurs génériques.
Récapitulatif
Vous avez écrit un map générique pour les conteneurs.
Functor<F>déclaremapsurKind<F, A>.- Les instances de tableau et d'option l'implémentent pour leurs URI.
- Le code générique comme
bumpAllfonctionne avec tout conteneur enregistré. - Les lois des foncteurs garantissent le bon comportement des instances ; des abstractions plus riches s'appuient sur elles.
Cours 24 ensuite : construire des analyseurs syntaxiques sûrs du point de vue des types.
Questions Fréquemment Posées
La leçon « Foncteurs et mappeurs génériques » est-elle gratuite ?
Oui — le texte complet de « Foncteurs et mappeurs génériques » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours TypeScript Academy, passe à CoddyKit PRO. Le cours TypeScript Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Foncteurs et mappeurs génériques » ?
Écrire des fonctions map génériques pour tout conteneur. Tu pratiques TypeScript Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer TypeScript Academy ?
Aucune expérience préalable n'est requise. TypeScript Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.
Combien de temps prend la leçon « Foncteurs et mappeurs génériques » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon TypeScript Academy ?
Oui. Chaque leçon TypeScript Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Le problème des HKT dans TypeScript
- Définir des constructeurs de types
- Le modèle HKT léger
- Foncteurs et mappeurs génériques