9 points par bboydart91 2026-02-08 | Aucun commentaire pour le moment. | Partager sur WhatsApp

Texte principal

  • Explication, à l’aide de code TypeScript, du chemin qui mène des deux problèmes que le seul map des foncteurs ne peut pas résoudre (le problème des fonctions piégées dans un conteneur et le problème de l’imbrication des contextes lors de la composition) jusqu’aux foncteurs applicatifs et aux monades
  • Le propos part du contexte dans lequel, en 1988, Eugenio Moggi a modélisé les programmes non pas comme A → B, mais comme A → T(B)
  • Présentation de la structure flatMap = map + join et des trois lois permettant de l’utiliser en toute sûreté (associativité, identité à gauche, identité à droite)
  • Explication de la raison pour laquelle une monade est « un objet monoïde dans la catégorie des endofoncteurs », en la comparant au monoïde de l’addition des entiers
  • Mention également de la raison pour laquelle Promise fonctionne de manière monadique sans pour autant être une monade mathématique au sens strict

Les limites des foncteurs : ce que map ne permet pas de faire

  • Si l’on applique une fonction curryfiée avec map, le résultat prend la forme de Maybe<(b: number) => number>, et la fonction reste piégée à l’intérieur du conteneur
    • map ne peut recevoir que des fonctions extérieures au conteneur ; il n’existe donc aucun moyen d’appliquer à une autre valeur une fonction enfermée à l’intérieur
  • Si l’on compose deux fonctions qui retournent des foncteurs, le contexte s’imbrique sous une forme comme Maybe<Maybe>
    • À mesure que les étapes s’accumulent, on obtient une imbrication infinie du type Maybe<Maybe<Maybe<...>>>

Foncteur applicatif : appliquer une fonction à l’intérieur d’un conteneur

  • L’opération apply permet d’appliquer une fonction enfermée dans un conteneur à la valeur d’un autre conteneur
    • apply: T<(A → B)> → T<A> → T<B>
  • L’opération pure permet d’insérer une valeur pure dans un conteneur
  • Limite : il faut savoir à l’avance quels conteneurs seront composés
    • Impossible d’exprimer une dépendance séquentielle dynamique où le calcul suivant est déterminé à partir du résultat du calcul précédent

Monade : l’invention d’une opération qui aplatit l’imbrication

  • L’opération join, de type T<T<A>> → T<A>, aplatit un double conteneur en un seul
    • Array.prototype.flat en JavaScript joue le même rôle
  • En pratique, on utilise flatMap, qui combine map et join
    • flatMap: T<A> → (A → T<B>) → T<B>
    • Alors que map reçoit A → B, flatMap reçoit A → T<B>, ce qui permet de conserver un seul niveau dans le résultat

Les trois lois de flatMap

  • Loi d’associativité : lors du dépliage d’une triple imbrication T(T(T(A))), le résultat doit être identique qu’on aplatisse d’abord l’intérieur ou l’extérieur
    • m.flatMap(f).flatMap(g) === m.flatMap(x => f(x).flatMap(g))
  • Loi d’identité à gauche : si l’on injecte une valeur avec pure puis qu’on applique immédiatement flatMap, le résultat est identique à l’application directe de la fonction
    • pure(a).flatMap(f) === f(a)
  • Loi d’identité à droite : si l’on passe pure à flatMap, on retrouve le conteneur d’origine
    • m.flatMap(pure) === m

Décomposition de « l’objet monoïde dans la catégorie des endofoncteurs »

  • En programmation, les foncteurs vont du monde des types vers le monde des types ; ce sont donc des endofoncteurs
  • On peut construire une catégorie des endofoncteurs, dont les objets sont les endofoncteurs eux-mêmes
  • Si l’on applique les conditions d’un monoïde (opération binaire + loi d’associativité + élément neutre), on obtient :
    • opération binaire = join
    • élément neutre = pure
    • la structure correspond exactement à celle du monoïde de l’addition des entiers

Pourquoi Promise n’est pas une monade

  • then mélange le comportement de map et de flatMap selon la valeur de retour
  • Un état Promise<Promise> n’est pas autorisé à l’exécution et est immédiatement fusionné en une seule couche
  • C’est pratique en développement, mais cela ne satisfait pas les lois d’une monade mathématique

Aucun commentaire pour le moment.

Aucun commentaire pour le moment.