0Pricing
TypeScript Academy · Leçon

Le modèle HKT léger

Mettre en œuvre l’astuce de défonctionnalisation Kind/URI.

Le modèle HKT léger est une leçon TypeScript Academy gratuite sur CoddyKit. Ceci est la leçon 3 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.

Défonctionnalisation

L'astuce qui se trouve derrière l'encodage porte un nom : la défonctionnalisation. Au lieu d'une véritable fonction de type d'ordre supérieur, nous représentons chaque fonction par une étiquette et la résolvons au moyen d'une seule recherche du premier ordre. Le registre URItoKind est cette table de recherche.

type Kind<F extends URIS, A> = URItoKind<A>[F];
// One lookup replaces true type-function application

Le type de constructeur

Kind<F, A> est la façade publique du modèle. Lisez-le comme « le constructeur F appliqué à A ». Il dissimule l'indexation du registre derrière un nom clair.

type A = Kind<"Array", number>;  // number[]
type B = Kind<"Option", string>; // string | null

Contraindre F à URIS

F doit être un URI enregistré. Contraignez-le avec extends URIS afin que seules les étiquettes valides puissent être utilisées et que les fautes de frappe deviennent des erreurs de compilation.

type Kind<F extends URIS, A> = URItoKind<A>[F];

// Kind<"Arrey", number> -> error, not a valid URI

Écrire des signatures génériques

Nous pouvons maintenant écrire la signature auparavant impossible de Functor. Remplacez chaque F<A> par Kind<F, A> et le compilateur l'accepte.

interface Functor<F extends URIS> {
  map<A, B>(fa: Kind<F, A>, f: (a: A) => B): Kind<F, B>;
}

La résolution en pratique

Lorsque vous fixez F à un URI concret, Kind se résout en type de conteneur réel. Un Functor<"Array"> possède un map allant de A[] à B[].

type ArrayFunctor = Functor<"Array">;
// map: <A, B>(fa: A[], f: (a: A) => B) => B[]

Plusieurs arguments de type

Certains constructeurs prennent deux arguments, comme Either<E, A>. fp-ts étend le modèle avec URItoKind2 et Kind2<F, E, A> pour la forme * -> * -> *. L'idée s'étend en ajoutant d'autres registres.

interface URItoKind2<E, A> {
  Either: { left: E } | { right: A };
}
type Kind2<F extends URIS2, E, A> = URItoKind2<E, A>[F];

La convention de fp-ts

fp-ts a établi la convention suivie par tout ce cours : une chaîne URI par type de données, un registre URItoKind étendu par fusion des déclarations, et Kind pour la résolution. La reconnaître vous permet de lire les signatures de types de fp-ts et d'Effect.

// In fp-ts you will see exactly:
// declare module "fp-ts/HKT" { interface URItoKind<A> { ... } }

Un enregistrement d'instance

Une « instance » d'une abstraction est une valeur qui l'implémente pour un URI précis. L'instance contient le map concret. Nous écrirons l'instance de tableau dans la prochaine leçon ; en voici la forme.

declare const arrayFunctor: Functor<"Array">;
const out = arrayFunctor.map([1, 2, 3], n => n * 2); // number[]

Pourquoi ce modèle est « léger »

On l'appelle le modèle HKT léger, car il ne nécessite ni modification du compilateur ni syntaxe spéciale : seulement des interfaces et des accès indexés. En contrepartie d'un peu de formalisme (URI, registres), il permet d'écrire du code réellement générique pour les conteneurs.

type Kind<F extends URIS, A> = URItoKind<A>[F];
// No magic, just a typed lookup table

Limites

Le modèle est verbeux et les messages d'erreur peuvent être difficiles à interpréter, car ils mentionnent l'encodage plutôt que votre domaine. Il exige également que chaque conteneur soit enregistré. Dans la plupart des applications, vous utilisez des bibliothèques qui le font déjà au lieu de le construire vous-même.

// Trade-off: real abstraction power vs. encoding ceremony

Tout assembler

La recette complète du modèle HKT léger est la suivante : définir un URI, l'enregistrer dans URItoKind, définir des abstractions avec Kind<F, A> et fournir des instances pour chaque URI. C'est toute la boîte à outils qui se trouve derrière les bibliothèques fonctionnelles génériques de TypeScript.

type Kind<F extends URIS, A> = URItoKind<A>[F];
interface Functor<F extends URIS> {
  map<A, B>(fa: Kind<F, A>, f: (a: A) => B): Kind<F, B>;
}

Vérification rapide

Vérifiez votre compréhension du modèle HKT léger.

Récapitulatif

Vous avez assemblé le modèle HKT léger.

  • La défonctionnalisation remplace l'application d'une fonction de type par une recherche.
  • Kind<F, A> résout un URI et un argument en type concret.
  • Les signatures génériques utilisent Kind plutôt que F<A>.
  • Le modèle s'étend à deux arguments avec Kind2 et constitue la convention de fp-ts.

Ensuite : un map générique avec de vraies instances.

Questions Fréquemment Posées

La leçon « Le modèle HKT léger » est-elle gratuite ?

Oui — le texte complet de « Le modèle HKT léger » 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 « Le modèle HKT léger » ?

Mettre en œuvre l’astuce de défonctionnalisation Kind/URI. 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 3 sur 4.

Combien de temps prend la leçon « Le modèle HKT léger » ?

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

  1. Le problème des HKT dans TypeScript
  2. Définir des constructeurs de types
  3. Le modèle HKT léger
  4. Foncteurs et mappeurs génériques
← Retour à TypeScript Academy