{"id":16365967,"url":"https://github.com/marcwrobel/functional-programming-jargon-fr","last_synced_at":"2025-08-14T19:20:29.278Z","repository":{"id":62314662,"uuid":"557427949","full_name":"marcwrobel/functional-programming-jargon-fr","owner":"marcwrobel","description":"Le jargon du monde de la programmation fonctionnelle en termes simples !","archived":false,"fork":false,"pushed_at":"2024-01-17T20:19:44.000Z","size":379,"stargazers_count":15,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-08-12T00:45:50.395Z","etag":null,"topics":["fp","functional-programming","programmation-fonctionnelle"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marcwrobel.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":"contributing.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"hemanth","patreon":"fpjargon","custom":"https://paypal.me/gnumanth"}},"created_at":"2022-10-25T17:09:30.000Z","updated_at":"2025-08-01T21:55:53.000Z","dependencies_parsed_at":"2024-01-17T21:46:05.823Z","dependency_job_id":"f7e6099a-4182-4fed-904e-58a4ed2169ab","html_url":"https://github.com/marcwrobel/functional-programming-jargon-fr","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/marcwrobel/functional-programming-jargon-fr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcwrobel%2Ffunctional-programming-jargon-fr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcwrobel%2Ffunctional-programming-jargon-fr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcwrobel%2Ffunctional-programming-jargon-fr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcwrobel%2Ffunctional-programming-jargon-fr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcwrobel","download_url":"https://codeload.github.com/marcwrobel/functional-programming-jargon-fr/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcwrobel%2Ffunctional-programming-jargon-fr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270469746,"owners_count":24589243,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-14T02:00:10.309Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fp","functional-programming","programmation-fonctionnelle"],"created_at":"2024-10-11T02:44:54.853Z","updated_at":"2025-08-14T19:20:29.244Z","avatar_url":"https://github.com/marcwrobel.png","language":null,"funding_links":["https://github.com/sponsors/hemanth","https://patreon.com/fpjargon","https://paypal.me/gnumanth"],"categories":[],"sub_categories":[],"readme":"# Le jargon de la programmation fonctionnelle\n\n\u003e Ce document est une traduction française de\n\u003e [hemanth/functional-programming-jargon](https://github.com/hemanth/functional-programming-jargon)\n\u003e basée sur le commit [ce4cc3e](https://github.com/hemanth/functional-programming-jargon/commit/08a48ff).\n\nLa programmation fonctionnelle offre de nombreux avantages et sa popularité n’a cessé d’augmenter en conséquence.\nCependant, chaque paradigme de programmation défini son propre jargon et la programmation fonctionnelle ne fait pas\nexception. En fournissant un glossaire, nous espérons faciliter l’apprentissage de la programmation fonctionnelle.\n\nLes exemples sont écrits en JavaScript (ES2015).\n[Pourquoi JavaScript ?](https://github.com/hemanth/functional-programming-jargon/wiki/Why-JavaScript%3F)\n\nLorsque cela est possible, ce document utilise les termes définis dans la\n[spécification Fantasy Land](https://github.com/fantasyland/fantasy-land).\n\n__Traductions__\n\n* [Portugaise](https://github.com/alexmoreno/jargoes-programacao-funcional)\n* [Espagnole](https://github.com/idcmardelplata/functional-programming-jargon/tree/master)\n* [Chinoise](https://github.com/shfshanyue/fp-jargon-zh)\n* [Indonésienne](https://github.com/wisn/jargon-pemrograman-fungsional)\n* [Anglaise (exemples en Python)](https://github.com/jmesyou/functional-programming-jargon.py)\n* [Anglaise (exemples en Scala)](https://github.com/ikhoon/functional-programming-jargon.scala)\n* [Anglaise (exemples en Rust)](https://github.com/JasonShin/functional-programming-jargon.rs)\n* [Coréenne](https://github.com/sphilee/functional-programming-jargon)\n* [Polonaise](https://github.com/Deloryn/functional-programming-jargon)\n* [Turque (exemples en Haskell)](https://github.com/mrtkp9993/functional-programming-jargon)\n* [Russe (exemples en Haskell)](https://github.com/epogrebnyak/functional-programming-jargon)\n* [Anglaise (exemples en Julia)](https://github.com/Moelf/functional-programming-jargon.jl)\n\n__Table des matières__\n\u003c!-- RM(noparent,notop) --\u003e\n\n* [Arité](#arité)\n* [Fonction d’ordre supérieur](#fonction-dordre-supérieur)\n* [Fermeture](#fermeture)\n* [Application partielle](#application-partielle)\n* [Curryfication](#curryfication)\n* [Auto-curryfication](#auto-curryfication)\n* [Composition de fonctions](#composition-de-fonctions)\n* [Continuation](#continuation)\n* [Fonction pure](#fonction-pure)\n* [Effets de bord](#effets-de-bord)\n* [Idempotence](#idempotence)\n* [Programmation tacite](#programmation-tacite)\n* [Prédicat](#prédicat)\n* [Contrats](#contrats)\n* [Catégorie](#catégorie)\n* [Valeur](#valeur)\n* [Constante](#constante)\n  * [Fonction constante](#fonction-constante)\n  * [Foncteur constant](#foncteur-constant)\n  * [Monade constante](#monade-constante)\n* [Foncteur](#foncteur)\n* [Foncteur pointé](#foncteur-pointé)\n* [Relèvement](#relèvement)\n* [Transparence référentielle](#transparence-référentielle)\n* [Raisonnement équationnel](#raisonnement-équationnel)\n* [Lambda](#lambda)\n* [Lambda-calcul](#lambda-calcul)\n* [Combinateur fonctionnel](#combinateur-fonctionnel)\n* [Évaluation paresseuse](#évaluation-paresseuse)\n* [Monoïde](#monoïde)\n* [Monade](#monade)\n* [Comonade](#comonade)\n* [Composition de Kleisli](#composition-de-kleisli)\n* [Foncteur applicatif](#foncteur-applicatif)\n* [Morphisme](#morphisme)\n  * [Homomorphisme](#homomorphisme)\n  * [Endomorphisme](#endomorphisme)\n  * [Isomorphisme](#isomorphisme)\n  * [Catamorphisme](#catamorphisme)\n  * [Anamorphisme](#anamorphisme)\n  * [Hylomorphisme](#hylomorphisme)\n  * [Paramorphisme](#paramorphisme)\n  * [Apomorphisme](#apomorphisme)\n* [Setoïde](#setoïde)\n* [Demi-groupe](#demi-groupe)\n* [Foldable](#foldable)\n* [Lentille](#lentille)\n* [Signatures de type](#signatures-de-type)\n* [Type algébrique de données](#type-algébrique-de-données)\n  * [Types somme](#types-somme)\n  * [Types produit](#types-produit)\n* [Option](#option)\n* [Fonction](#fonction)\n* [Fonction partielle](#fonction-partielle)\n  * [Manipuler des fonctions partielles](#manipuler-des-fonctions-partielles)\n* [Fonction totale](#fonction-totale)\n* [Bibliothèques de programmation fonctionnelle en JavaScript](#bibliothèques-de-programmation-fonctionnelle-en-javascript)\n\n\u003c!-- /RM --\u003e\n\n## Arité\n\nL'arité (_arity_ en anglais) est le nombre d’arguments déclaré par une fonction. On utilise aussi des mots comme unaire,\nbinaire ou ternaire pour désigner le nombre d'arguments.\n\n```js\nconst somme = (a, b) =\u003e a + b // l’arité est 2 (binaire)\nconst inc = a =\u003e a + 1 // l’arité est 1 (unaire)\nconst zero = () =\u003e 0 // l’arité est 0 (nullaires)\n```\n\n__Pour aller plus loin__\n\n* [Arité](https://fr.wikipedia.org/wiki/Arit%C3%A9) sur Wikipédia\n\n## Fonction d’ordre supérieur\n\nUne fonction d’ordre supérieur (_higher-order functions_ ou _HOF_ en anglais) est une fonction prenant une autre\nfonction en argument et/ou renvoyant une autre fonction.\n\n```js\nconst filtre = (predicat, elements) =\u003e elements.filter(predicat)\nconst est = (type) =\u003e (element) =\u003e Object(element) instanceof type\n\nfiltre(est(Number), [0, '1', 2, null]) // [0, 2]\n```\n\n__Pour aller plus loin__\n\n* [Fonction d’ordre supérieur](https://fr.wikipedia.org/wiki/Fonction_d%27ordre_sup%C3%A9rieur) sur Wikipédia\n\n## Fermeture\n\nUne fermeture (_closure_ en anglais) est une fonction accompagnée de l’ensemble des variables locales qu’elle a\ncapturées au moment où elle a été définie. Ces variables restent alors accessibles même après que le programme soit\nsorti du bloc où elles ont été définies.\n\n```js\nconst ajouterA = x =\u003e y =\u003e x + y\nconst ajouterACinq = ajouterA(5)\najouterACinq(3) // =\u003e 8\n```\n\nDans l’exemple, `x` a été capturée par la fermeture `ajouterACinq` avec la valeur `5`. `ajouterACinq` peut alors être\nappelée avec `y` pour retourner la somme.\n\n__Pour aller plus loin__\n\n* [Closures (Fermetures)](https://developer.mozilla.org/fr/docs/Web/JavaScript/Closures) sur MDN\n* [Lambda Vs Closure (en)](http://stackoverflow.com/questions/220658/what-is-the-difference-between-a-closure-and-a-lambda)\n* [JavaScript Closures highly voted discussion (en)](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work)\n\n## Application partielle\n\nL'application partielle d’une fonction (_partial application_ en anglais) est le processus visant à créer une nouvelle\nfonction en préremplissant certains des arguments de la fonction originale.\n\n```js\n// permet de créer des fonctions appliquées partiellement\n// prend en paramètre une fonction et des arguments\nconst appliquerPartiellement = (f, ...args) =\u003e\n  // retourne une function qui prend en paramètre le reste des arguments\n  (...resteDesArgs) =\u003e\n    // et appelle la fonction originale avec tous les arguments\n    f(...args, ...resteDesArgs)\n\n// une fonction à appliquer partiellement\nconst ajouter3 = (a, b, c) =\u003e a + b + c\n\n// Applique partiellement `2` et `3` à `ajouter3` produit une fonction à un argument\nconst cinqPlus = appliquerPartiellement(ajouter3, 2, 3) // (c) =\u003e 2 + 3 + c\n\ncinqPlus(4) // 9\n```\n\nIl est aussi possible d’utiliser `Function.prototype.bind` pour appliquer partiellement une fonction en JavaScript :\n\n```js\nconst cinqPlus = ajouter3.bind(null, 2, 3) // (c) =\u003e 2 + 3 + c\n```\n\nL’application partielle permet de créer des fonctions plus simples à partir de fonctions plus complexes en y intégrant\nles données au fur et à mesure où elles deviennent disponibles. Les fonctions [curryfiées](#curryfication) sont\nautomatiquement partiellement appliquées.\n\n__Pour aller plus loin__\n\n* [Partial application (en)](https://en.wikipedia.org/wiki/Partial_application) sur Wikipédia\n\n## Curryfication\n\nLa curryfication (_currying_ en anglais) est le processus de conversion d’une fonction qui prend plusieurs arguments en\nune fonction qui les prend un à la fois.\n\nChaque fois que la fonction est appelée, elle n’accepte qu’un seul argument et retourne une fonction qui prend un\nargument jusqu’à ce que tous les arguments soient passés.\n\n```js\nconst somme = (a, b) =\u003e a + b\n\nconst sommeCurryfiee = (a) =\u003e (b) =\u003e a + b\n\nsommeCurryfiee(40)(2) // 42\n\nconst ajouterDeux = sommeCurryfiee(2) // (b) =\u003e 2 + b\n\najouterDeux(10) // 12\n```\n\n__Pour aller plus loin__\n\n* [Curryfication](https://fr.wikipedia.org/wiki/Curryfication) sur Wikipédia\n\n## Auto-curryfication\n\nL'auto-curryfication (_auto currying_ en anglais) est la transformation d’une fonction qui prend plusieurs arguments en\nune fonction qui, si on lui donne moins que son nombre correct d’arguments, renvoie une fonction qui prend le reste des\narguments. Lorsque la fonction est appelée avec le nombre correct d’arguments, elle est ensuite évaluée.\n\n[Lodash](https://lodash.com/) et [Ramda](https://ramdajs.com/) ont une fonction `curry` qui marche comme suit :\n\n```js\nconst somme = (x, y) =\u003e x + y\n\nconst sommeCurryfiee = _.curry(somme)\nsommeCurryfiee(1, 2) // 3\nsommeCurryfiee(1) // (y) =\u003e 1 + y\nsommeCurryfiee(1)(2) // 3\n```\n\n__Pour aller plus loin__\n\n* [Favoring Curry (en)](http://fr.umio.us/favoring-curry/)\n* [Hey Underscore, You’re Doing It Wrong! (en)](https://www.youtube.com/watch?v=m3svKOdZijA)\n\n## Composition de fonctions\n\nLa composition de fonctions (_function composition_ en anglais) est l’acte d'assembler deux fonctions ensemble pour en\nformer une troisième, où la sortie d’une fonction est l’entrée de l’autre. C’est l’une des idées les plus importantes de\nla programmation fonctionnelle.\n\n```js\nconst composer = (f, g) =\u003e (a) =\u003e f(g(a)) // Définition\nconst arondirEtTransformerEnChaine = composer((val) =\u003e val.toString(), Math.floor) // Utilisation\narondirEtTransformerEnChaine(121.212121) // '121'\n```\n\n__Pour aller plus loin__\n\n* [Composition de fonctions](https://fr.wikipedia.org/wiki/Composition_de_fonctions) sur Wikipédia\n\n## Continuation\n\nÀ tout moment d’un programme, la partie du code qui n’a pas encore été exécutée est appelée _continuation_.\n\n```js\nconst afficher = (nombre) =\u003e console.log(`Nombre ${nombre}`)\n\nconst ajouterUnEtContinuer = (nombre, cc) =\u003e {\n  const resultat = nombre + 1\n  cc(resultat)\n}\n\najouterUnEtContinuer(2, afficher) // 'Nombre 3'\n```\n\nLes continuations sont souvent observées en programmation asynchrone lorsque le programme doit attendre de recevoir des\ndonnées avant de pouvoir continuer à s’exécuter. La réponse est généralement transmise au reste du programme, qui est la\ncontinuation, une fois qu’elle a été reçue.\n\n```js\nconst poursuivreLeProgrammeAvec = (donnees) =\u003e {\n  // Poursuit le programme avec les données en paramètre\n}\n\nlireFichierAsync('chemin/vers/fichier', (err, reponse) =\u003e {\n  if (err) {\n    // prend en charge l’erreur\n    return\n  }\n  poursuivreLeProgrammeAvec(reponse)\n})\n```\n\n__Pour aller plus loin__\n\n* [Continuation](https://fr.wikipedia.org/wiki/Continuation_(informatique)) sur Wikipédia\n\n## Fonction pure\n\nUne fonction pure (_pure function_ en anglais) est une fonction :\n\n* dont la valeur de retour n’est déterminée que par ses arguments,\n* qui ne produit pas d’effets secondaires.\n\nUne fonction pure doit toujours renvoyer le même résultat lorsqu’elle reçoit les mêmes arguments.\n\n```js\nconst saluer = (nom) =\u003e `Salut, ${nom}`\n\nsaluer('Brianne') // renvoie toujour 'Salut, Brianne'\n```\n\nLa fonction `saluer` suivante n'est pas pure, son résultat dépend de données stockées en dehors de la fonction :\n\n```js\nwindow.name = 'Brianne'\n\nconst saluer = () =\u003e `Salut, ${window.name}`\n\nsaluer() // \"Salut, Brianne\"\n```\n\nLa fonction `saluer` suivante n'est pas pure, l’état en dehors de la fonction est modifié.\n\n```js\nlet salutation\n\nconst saluer = (nom) =\u003e {\n  salutation = `Salut, ${nom}`\n}\n\nsaluer('Brianne')\nsalutation // \"Salut, Brianne\"\n```\n\n__Pour aller plus loin__\n\n* [Fonction pure](https://fr.wikipedia.org/wiki/Fonction_pure) sur Wikipédia\n\n## Effets de bord\n\nUne fonction ou une expression est dite à effet de bord (_side effects_ en anglais) si, en plus de renvoyer une valeur,\nelle interagit (lit ou écrit) avec son environnement externe et que ce dernier est mutable.\n\n```js\nconst differentAChaqueFois = new Date() // la date change continuellement\n\nconsole.log('Les entrées-sorties sont un effet de bord !')\n```\n\n__Pour aller plus loin__\n\n* [Effet de bord](https://fr.wikipedia.org/wiki/Effet_de_bord_(informatique)) sur Wikipédia\n\n## Idempotence\n\nUne fonction est idempotente (_idempotent_ en anglais) si, quand on l’applique à nouveau à son résultat, elle ne produit\npas un résultat différent.\n\n```js\nMath.abs(Math.abs(10)) // le résultat sera toujours 10 quelque soit le nombre d'appel à Math.abs\n\nsort(sort(sort([2, 1]))) // une fois la liste triée, le résultat ne change plus \n```\n\n__Pour aller plus loin__\n\n* [Idempotence](https://fr.wikipedia.org/wiki/Idempotence) sur Wikipédia\n\n## Programmation tacite\n\nLa programmation tacite (_tacit programming_ ou _point-free style_ en anglais) est une manière d’écrire une fonction en\nn’identifiant pas explicitement les arguments utilisés. Ce style de programmation requiert généralement les notions\nde [curryfication](#curryfication) ou d'autres [fonctions d’ordre supérieur](#fonction-dordre-supérieur).\n\n```js\n// Étant donné\nconst map = (fn) =\u003e (liste) =\u003e liste.map(fn)\nconst ajouter = (a) =\u003e (b) =\u003e a + b\n\n// Alors\n\n// Sans la programmation tacite - `nombres` est un argument explicite\nconst incrementerTout = (nombres) =\u003e map(ajouter(1))(nombres)\n\n// Avec la programmation tacite - La liste est un argument implicite\nconst incrementerTout2 = map(ajouter(1))\n```\n\nLes définitions de fonctions _point-free_ ressemblent à des affectations normales sans `function` ou `=\u003e`. Il convient\nde mentionner que les fonctions _point-free_ ne sont pas nécessairement meilleures que leurs homologues\nnon-_point-free_, car elles peuvent être plus difficiles à comprendre lorsqu’elles sont complexes.\n\n__Pour aller plus loin__\n\n* [Tacit programming](https://en.wikipedia.org/wiki/Tacit_programming) sur Wikipédia\n\n## Prédicat\n\nUn prédicat (_predicate_ en anglais) est une fonction qui retourne vrai ou faux pour une valeur donnée. Une utilisation\ncourante d’un prédicat est la fonction utilisée pour filtrer un tableau.\n\n```js\nconst predicat = (a) =\u003e a \u003e 2\n\n[1, 2, 3, 4].filter(predicat) // [3, 4]\n```\n\n## Contrats\n\nUn contrat (_contract_ en anglais) spécifie les obligations et les garanties de comportement qu’une fonction ou une\nexpression doit respecter lors de son exécution. C’est un ensemble de règles qui s’appliquent aux entrées et sorties\nd’une fonction ou d’une expression. Des erreurs sont levées quand le contrat n’est pas respecté.\n\n```js\n// Definie le contrat : int -\u003e boolean\nconst contrat = (entree) =\u003e {\n  if (typeof entree === 'number') return true\n  throw new Error('Contrat non respecté : attendu int -\u003e boolean')\n}\n\nconst ajouterUn = (nombre) =\u003e contrat(nombre) \u0026\u0026 nombre + 1\n\najouterUn(2) // 3\najouterUn('une chaine') // Contrat non respecté : attendu int -\u003e boolean\n```\n\n## Catégorie\n\nUne catégorie (_category_ en anglais), dans la théorie des catégories, est un ensemble composé d’objets et des\nmorphismes entre eux. En programmation, les types représentent généralement les objets et les fonctions représentent\nles morphismes.\n\nPour qu’une catégorie soit valide, trois règles doivent être respectées :\n\n1. Un morphisme d’identité, qui mappe un objet à lui-même, doit exister.\n   Si `a` est un objet d’une catégorie,\n   alors il doit y avoir une fonction de `a -\u003e a`.\n2. Les morphismes doivent pouvoir être composés.\n   Si `a`, `b`, and `c` sont des objets d’une catégorie,\n   `f` est un morphisme de `a -\u003e b` et `g` est un morphisme de `b -\u003e c`,\n   alors `g(f(x))` doit être équivalent à `(g • f)(x)`.\n3. La composition doit être associative.\n   `f • (g • h)` est équivalent à `(f • g) • h`\n\nPuisque ces règles régissent la composition à un niveau très abstrait, la théorie des catégories est excellente pour\ndécouvrir de nouvelles façons de composer des choses.\n\nÀ titre d’exemple, nous pouvons définir une catégorie Max en tant que classe :\n\n```js\n\nclass Max {\n  constructor (a) {\n    this.a = a\n  }\n\n  id () {\n    return this\n  }\n\n  compose (b) {\n    return this.a \u003e b.a ? this : b\n  }\n\n  toString () {\n    return `Max(${this.a})`\n  }\n}\n\nnew Max(2).compose(new Max(3)).compose(new Max(5)).id().id() // =\u003e Max(5)\n```\n\n__Pour aller plus loin__\n\n* [Théorie des catégories](https://fr.wikipedia.org/wiki/Th%C3%A9orie_des_cat%C3%A9gories) sur Wikipédia\n* [Category Theory for Programmers (en)](https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/)\n\n## Valeur\n\nUne valeur (_value_ en anglais) est tout ce qui peut être assigné à une variable.\n\n```js\n5\nObject.freeze({ nom: 'John', age: 30 }) // La fonction `freeze` renforce l’immutabilité.\n;(a) =\u003e a\n;[1]\nundefined\n```\n\n## Constante\n\nUne constante (_constant_ en anglais) est une variable qui ne peut pas être réaffectée une fois définie.\n\n```js\nconst cinq = 5\nconst john = Object.freeze({ name: 'John', age: 30 }) // La fonction `freeze` renforce l’immutabilité.\n```\n\nLes constantes sont [référentiellement transparentes](#transparence-référentielle). Cela veut dire qu’une constante peut\nêtre remplacée par la valeur qu’elle représente sans que le résultat du programme soit modifié.\n\nAvec les deux constantes ci-dessus, l’expression suivante renverra toujours `true`.\n\n```js\njohn.age + cinq === ({ name: 'John', age: 30 }).age + 5\n```\n\n__Pour aller plus loin__\n\n* [Constante](https://fr.wikipedia.org/wiki/Constante_(programmation_informatique)) sur Wikipédia\n\n### Fonction constante\n\nUne fonction constante (_constant function_ en anglais) est une fonction [curryfiée](#curryfication) qui ignore son\ndeuxième argument :\n\n```js\nconst constante = a =\u003e () =\u003e a\n\n;[1, 2].map(constante(0)) // =\u003e [0, 0]\n;[2, 3].map(constante(0)) // =\u003e [0, 0]\n```\n\n### Foncteur constant\n\nUn foncteur constant (_constant functor_ en anglais) est un object dont la fonction `map` ne transforme pas le contenu.\nVoir [Foncteur](#foncteur).\n\n```js\nConstante(1).map(n =\u003e n + 1) // =\u003e Constante(1)\n```\n\n### Monade constante\n\nUne monade constante (_constant monad_ en anglais) est un object dont la fonction `chain` ne transforme pas le contenu.\nVoir [Monade](#monade).\n\n```js\nConstante(1).chain(n =\u003e Constante(n + 1)) // =\u003e Constante(1)\n```\n\n## Foncteur\n\nUn foncteur (_functor_ en anglais) est un objet qui implémente une fonction `map` qui prend en paramètre une fonction\nqui sera exécutée sur son contenu. Un foncteur doit respecter deux règles :\n\n__Préserver l’identité__\n\n```js\nobjet.map(x =\u003e x) // = objet\n```\n\n__Être composable__\n\n```js\n// `f`, `g` sont des fonctions composables arbitraires\nobjet.map(x =\u003e g(f(x))) // = objet.map(f).map(g)\n```\n\nL’implémentation de référence d’[Option](#option) est un foncteur, en effet :\n\n```js\n// préserve l’identité\nSome(1).map(x =\u003e x) // = Some(1)\n\n// est composable\nconst f = x =\u003e x + 1\nconst g = x =\u003e x * 2\nSome(1).map(x =\u003e g(f(x))) // = Some(4)\nSome(1).map(f).map(g) // = Some(4)\n```\n\n__Pour aller plus loin__\n\n* [Foncteur](https://fr.wikipedia.org/wiki/Foncteur) sur Wikipédia\n\n## Foncteur pointé\n\nUn foncteur pointé (_pointed functor_ en anglais) est un objet avec une fonction `of` qui stocke _n’importe_ quelle\nvaleur.\n\nQuand ES2015 a ajouté `Array.of`, `Array` est devenu un foncteur pointé.\n\n```js\nArray.of(1) // [1]\n```\n\n## Relèvement\n\nLe relèvement (_lifting_ en anglais) est l’action de prendre une valeur et de la mettre dans un objet tel qu’un\n[foncteur](#foncteur-pointé). Si vous relevez une fonction dans un [foncteur applicatif](#foncteur-applicatif), vous\npouvez l’appliquer aux valeurs qui se trouvent également dans ce foncteur.\n\nCertaines implémentations ont une fonction appelée `lift` ou `liftA2` pour faciliter l’exécution de fonctions sur des\nfoncteurs.\n\n```js\nconst liftA2 = (f) =\u003e (a, b) =\u003e a.map(f).ap(b) // note: c’est bien `ap` et non `map`.\n\nconst mult = a =\u003e b =\u003e a * b\n\nconst multRelevé = liftA2(mult) // cette nouvelle fonction s’applique à des foncteurs comme Array\n\nmultRelevé([1, 2], [3]) // [3, 6]\nliftA2(a =\u003e b =\u003e a + b)([1, 2], [30, 40]) // [31, 41, 32, 42]\n```\n\nRelever une fonction à un argument et l’appliquer fait la même chose que `map`.\n\n```js\nconst incrementer = (x) =\u003e x + 1\n\nlift(incrementer)([2]) // [3]\n;[2].map(incrementer) // [3]\n```\n\nRelever de simples valeurs peut consister à créer uniquement l’objet.\n\n```js\nArray.of(1) // =\u003e [1]\n```\n\n## Transparence référentielle\n\nUne expression qui peut être remplacée par sa valeur sans changer le comportement du programme est dite\nréférentiellement transparente (_referentially transparent_ en anglais).\n\nÉtant donné la fonction `saluer` :\n\n```js\nconst saluer = () =\u003e 'Bonjour le monde !'\n```\n\nToute invocation de `saluer()` peut être remplacée par `Bonjour le monde !`, donc `saluer` est référentiellement\ntransparente. Cela ne serait pas le cas si `saluer` dépendait d’un état externe comme de la configuration ou un appel à\nune base de données. Voir aussi [fonction pure](#fonction-pure), [raisonnement équationnel](#raisonnement-équationnel).\n\n__Pour aller plus loin__\n\n* [Transparence référentielle](https://fr.wikipedia.org/wiki/Transparence_r%C3%A9f%C3%A9rentielle) sur Wikipédia\n\n## Raisonnement équationnel\n\nLorsqu’une application est composée d’expressions et dépourvue d’effets secondaires, des affirmations peuvent être\ndéduites de ses parties. Vous pouvez également être sûr des détails de votre programme sans avoir à parcourir toutes les\nfonctions.\n\n```js\nconst grainesDansChiens = compose(pouletsDansChiens, grainesDansPoulets)\nconst grainesDansChats = compose(chiensDansChats, grainesDansChiens)\n```\n\nDans l’exemple ci-dessus, si vous savez que `pouletsDansChiens` et `grainesDansPoulets` sont [pures](#fonction-pure),\nalors vous savez que la composition est également pure. Les choses peuvent être poussées un peu plus loin lorsque l’on\nen sait plus sur les fonctions (associativité, commutativité, idempotence, etc...).\n\n## Lambda\n\nUne fonction anonyme qui peut être traitée comme une valeur.\n\n```js\n;(function (a) {\n  return a + 1\n})\n\n;(a) =\u003e a + 1\n```\n\nLes lambdas sont souvent utilisées en tant qu’arguments de fonctions d’ordre supérieur.\n\n```js\n;[1, 2].map((a) =\u003e a + 1) // [2, 3]\n```\n\nUne lambda peut être affectée à une variable :\n\n```js\nconst ajouter1 = (a) =\u003e a + 1\n```\n\n## Lambda-calcul\n\nUne branche des mathématiques qui utilise les fonctions pour créer un\n[modèle universel de calcul](https://fr.wikipedia.org/wiki/Lambda-calcul).\n\n## Combinateur fonctionnel\n\nUn combinateur fonctionnel (_functional combinator_ en anglais) est une\n[fonction d’ordre supérieur](##fonction-dordre-supérieur), généralement [curryfiée](#curryfication), qui renvoie une\nnouvelle fonction modifiée d’une manière ou d’une autre.\n\nLes combinateurs fonctionnels sont souvent utilisés en [programmation tacite](#programmation-tacite) pour écrire des\nprogrammes particulièrement concis.\n\n```js\n// Le combinateur \"C\" prend une fonction curryfiée à deux arguments et\n// en renvoie une nouvelle qui appelle la fonction d’origine avec les arguments inversés.\nconst C = (f) =\u003e (a) =\u003e (b) =\u003e f(b)(a)\n\nconst diviser = (a) =\u003e (b) =\u003e a / b\n\nconst diviserPar = C(diviser)\n\nconst diviserPar10 = diviserPar(10)\n\ndiviserPar10(30) // =\u003e 3\n```\n\n__Pour aller plus loin__\n\n* [Logique combinatoire](https://fr.wikipedia.org/wiki/Logique_combinatoire) sur Wikipédia\n* [liste des combinateurs fonctionnels en JavaScript (en)](https://gist.github.com/Avaq/1f0636ec5c8d6aed2e45)\n\n## Évaluation paresseuse\n\nL’évaluation paresseuse (_lazy evaluation_ en anglais) est un mécanisme qui retarde l’évaluation d’une expression\njusqu’à ce que sa valeur soit nécessaire. Dans les langages fonctionnels, cela permet des structures telles que les\nlistes infinies, qui ne seraient normalement pas disponibles dans un langage impératif où l’enchaînement des commandes\nest important.\n\n```js\nconst rand = function * () {\n  while (1 \u003c 2) {\n    yield Math.random()\n  }\n}\n\nconst randIter = rand()\nrandIter.next() // Chaque exécution donne une valeur aléatoire, l’expression est évaluée au besoin.\n```\n\n__Pour aller plus loin__\n\n* [Évaluation paresseuse](https://fr.wikipedia.org/wiki/%C3%89valuation_paresseuse) sur Wikipédia\n\n## Monoïde\n\nUn monoïde (_monoid_ en anglais) est un objet avec une fonction qui « combine » cet objet avec un autre du même type\n([demi-groupe](#demi-groupe)) et qui a de plus une valeur neutre.\n\nUn exemple de monoïde simple est l’addition de nombres :\n\n```js\n1 + 1 // 2\n```\n\nDans ce cas, le nombre est l’objet et `+` est la fonction.\n\nLorsqu’une valeur est combinée avec la valeur neutre, le résultat doit être la valeur d’origine. La fonction doit\négalement être commutative dans ce cas. La valeur neutre pour l’addition est `0` :\n\n```js\n1 + 0 // 1\n0 + 1 // 1\n1 + 0 === 0 + 1\n```\n\nIl est également nécessaire que le regroupement des opérations n’influe pas sur le résultat (associativité) :\n\n```js\n1 + (2 + 3) === (1 + 2) + 3 // true\n```\n\nLa concaténation de tableaux forme également un monoïde dont la valeur neutre est un tableau vide (`[]`) :\n\n```js\n;[1, 2].concat([3, 4]) // [1, 2, 3, 4]\n;[1, 2].concat([]) // [1, 2]\n```\n\nÀ titre de contre-exemple, la soustraction ne forme pas de monoïde car il n’existe pas de valeur neutre commutative :\n\n```js\n0 - 4 === 4 - 0 // false\n```\n\n__Pour aller plus loin__\n\n* [Monoïde](https://fr.wikipedia.org/wiki/Mono%C3%AFde) sur Wikipédia\n\n## Monade\n\nUne monade (_monad_ en anglais) est un objet avec les fonctions [`of`](#foncteur-pointé) et `chain`. La fonction `chain`\nest comme [`map`](#foncteur) sauf qu’elle désimbrique les objets imbriqués résultants.\n\n```js\n// Implémentation\nArray.prototype.chain = function (f) {\n  return this.reduce((acc, it) =\u003e acc.concat(f(it)), [])\n}\n\n// Utilisation\nArray.of('chat,chien', 'poisson,oiseau').chain((a) =\u003e a.split(',')) // ['chat', 'chien', 'poisson', 'oiseau']\n\n// Contraste avec map\nArray.of('chat,chien', 'poisson,oiseau').map((a) =\u003e a.split(',')) // [['chat', 'chien'], ['poisson', 'oiseau']]\n```\n\n`of` est également connu sous le nom de `return` dans d’autres langages fonctionnels. Et `chain` est connu sous le nom\nde `flatmap` ou `bind`.\n\n__Pour aller plus loin__\n\n* [Monade](https://fr.wikipedia.org/wiki/Monade_(informatique)) sur Wikipédia\n\n## Comonade\n\nUne comonade (_comonad_ en anglais) est objet qui a les fonctions `extract` et `extend`.\n\n```js\nconst CoIdentité = (v) =\u003e ({\n  val: v,\n  extract () {\n    return this.val\n  },\n  extend (f) {\n    return CoIdentité(f(this))\n  }\n})\n```\n\n`extract` extrait une valeur d’un foncteur :\n\n```js\nCoIdentité(1).extract() // 1\n```\n\n`extend` exécute une fonction sur la comonade. La fonction doit renvoyer le même type que la comonade :\n\n```js\nCoIdentité(1).extend((co) =\u003e co.extract() + 1) // CoIdentité(2)\n```\n\n__Pour aller plus loin__\n\n* [Comonads (en)](https://en.wikipedia.org/wiki/Monad_(category_theory)#Comonads) sur Wikipédia\n\n## Composition de Kleisli\n\nUne composition de Kleisli (_Kleisli composition_ en anglais) est une opération pour composer deux fonctions qui\nretournent des [monades](#monade) (flèches de Kleisli) quand elles ont des types compatibles. En Haskell, il s’agit de\nl’opérateur `\u003e=\u003e`.\n\nEn JavaScript, en utilisant [les options](#option) :\n\n```js\n// safeParseNum :: String -\u003e Option Number\nconst safeParseNum = (b) =\u003e {\n  const n = parseNumber(b)\n  return isNaN(n) ? None() : Some(n)\n}\n\n// validatePositive :: Number -\u003e Option Number\nconst validatePositive = (a) =\u003e a \u003e 0 ? Some(a) : None()\n\n// kleisliCompose :: Monad M =\u003e ((b -\u003e M c), (a -\u003e M b)) -\u003e a -\u003e M c\nconst kleisliCompose = (g, f) =\u003e (x) =\u003e f(x).chain(g)\n\n// parseAndValidate :: String -\u003e Option Number\nconst parseAndValidate = kleisliCompose(validatePositive, safeParseNum)\n\nparseAndValidate('1') // =\u003e Some(1)\nparseAndValidate('asdf') // =\u003e None\nparseAndValidate('999') // =\u003e Some(999)\n```\n\nCeci fonctionne car :\n\n* [Option](#option) est une [monade](#monade)\n* `validatePositive` et `safeParseNum` renvoient le même type de monade (Option).\n* Le type d’argument de `validatePositive` correspond au retour non encapsulé de `safeParseNum`.\n\n__Pour aller plus loin__\n\n* [Catégorie de Kleisli](https://fr.wikipedia.org/wiki/Cat%C3%A9gorie_de_Kleisli) sur Wikipédia\n\n## Foncteur applicatif\n\nUn foncteur applicatif (_applicative functor_ en anglais) est un objet avec une fonction `ap`. `ap` applique une\nfonction de l’objet à une valeur d’un autre objet du même type.\n\n```js\n// Implémentation\nArray.prototype.ap = function (elements) {\n  return this.reduce((acc, f) =\u003e acc.concat(elements.map(f)), [])\n}\n\n// Exemple d’utilisation\n;[(a) =\u003e a + 1].ap([1]) // [2]\n```\n\nC’est très utile quand vous avez deux objets et que vous souhaitez appliquer une fonction binaire à leurs contenus.\n\n```js\n// Tableaux que vous souhaitez fusionner\nconst arg1 = [1, 3]\nconst arg2 = [4, 5]\n\n// fonction de fusion - doit être curryfiée pour que cela fonctionne\nconst ajouter = (x) =\u003e (y) =\u003e x + y\n\nconst ajoutsPartiels = [ajouter].ap(arg1) // [(y) =\u003e 1 + y, (y) =\u003e 3 + y]\n```\n\nCela vous donne un tableau de fonctions sur lequel vous pouvez appeler `ap` pour obtenir le résultat final :\n\n```js\najoutsPartiels.ap(arg2) // [5, 6, 7, 8]\n```\n\n__Pour aller plus loin__\n\n* [Applicative functor](https://en.wikipedia.org/wiki/Applicative_functor) sur Wikipédia\n\n## Morphisme\n\nUn morphisme (_morphism_ en anglais) est une relation entre des objets au sein d’une [catégorie](#catégorie). En\nprogrammation fonctionnelle, toutes les fonctions sont des morphismes.\n\n__Pour aller plus loin__\n\n* [Morphisme](https://fr.wikipedia.org/wiki/Morphisme) sur Wikipédia\n\n### Homomorphisme\n\nUn homomorphisme (_homomorphism_ en anglais) et une fonction où l’entrée et la sortie partagent une même propriété\nstructurelle. Par exemple, dans un homomorphisme [monoïde](#monoïde), l’entrée et la sortie sont des monoïdes même si\nleurs types sont différents.\n\n```js\n// convertir :: [number] -\u003e string\nconst convertir = (a) =\u003e a.join(', ')\n```\n\n`convertir` est un homomorphisme car :\n\n* array est un monoïde - il possède une opération `concat` et une valeur neutre (`[]`),\n* string est un monoïde - il possède une opération `concat` et une valeur neutre (`''`).\n\nAinsi, un homomorphisme se rapporte à la propriété qui vous intéresse dans l’entrée et la sortie d’une fonction de\ntransformation.\n\nLes [endomorphismes](#endomorphisme) et les [isomorphismes](#isomorphisme) sont des exemples d’homomorphisme.\n\n__Pour aller plus loin__\n\n* [Homomorphism | Learning Functional Programming in Go (en)](https://subscription.packtpub.com/book/application-development/9781787281394/11/ch11lvl1sec90/homomorphism#:~:text=A%20homomorphism%20is%20a%20correspondence,pointing%20to%20it%20from%20A.)\n\n### Endomorphisme\n\nUn endomorphisme (_endomorphism_ en anglais) est fonction où le type de l’entrée est identique à celui de sortie.\n\n```js\n// majuscule :: String -\u003e String\nconst enMajuscule = (str) =\u003e str.toUpperCase()\n\n// decrementer :: Number -\u003e Number\nconst decrementer = (x) =\u003e x - 1\n```\n\n__Pour aller plus loin__\n\n* [Endomorphisme](https://fr.wikipedia.org/wiki/Endomorphisme) sur Wikipédia\n\n### Isomorphisme\n\nUn isomorphisme (_isomorphism_ en anglais) est un morphisme pour lequel il existe un morphisme inverse. Ce type de\nmorphismes préserve la structure des objets.\n\nPar exemple, les coordonnées 2D peuvent être stockées sous forme de tableau (`[2,3]`) ou d’objet (`{x: 2, y: 3}`).\n\n```js\n// Fonctions de conversions\nconst paireVersCoords = (paire) =\u003e ({ x: paire[0], y: paire[1] })\nconst coordsVersPaire = (coords) =\u003e [coords.x, coords.y]\n\ncoordsVersPaire(paireVersCoords([1, 2])) // [1, 2]\npaireVersCoords(coordsVersPaire({ x: 1, y: 2 })) // {x: 1, y: 2}\n```\n\nLes isomorphismes sont aussi des [homomorphismes](#homomorphisme) puisque les types d’entrée et de sortie sont\nréversibles.\n\n__Pour aller plus loin__\n\n* [Isomorphisme](https://fr.wikipedia.org/wiki/Isomorphisme) sur Wikipédia\n\n### Catamorphisme\n\nUn catamorphisme (_catamorphism_ en anglais) est ue fonction qui déconstruit une structure en une seule valeur.\n`reduceRight` est un exemple de catamorphisme pour les structures de type tableau.\n\n```js\n// somme est un catamorphisme de [Number] -\u003e Number\nconst somme = nombres =\u003e nombres.reduceRight((accumulateur, nombre) =\u003e accumulateur + nombre, 0)\n\nsomme([1, 2, 3, 4, 5]) // 15\n```\n\n__Pour aller plus loin__\n\n* [Catamorphisme](https://fr.wikipedia.org/wiki/Catamorphisme) sur Wikipédia\n\n### Anamorphisme\n\nUn anamorphisme (_anamorphism_ en anglais) est une fonction qui construit une structure en appliquant de manière répétée\nune autre fonction à son argument. C’est le contraire d’un [catamorphisme](#catamorphisme) : l'anamorphisme construit\nune structure et le catamorphisme la décompose.\n\n```js\n// génère un tableau à partir d’une fonction et d’une valeur initiale. \nconst deplier = (f, valeurInitiale) =\u003e {\n  function appliquer (f, valeurInitiale, acc) {\n    const res = f(valeurInitiale)\n    return res ? appliquer(f, res[1], acc.concat([res[0]])) : acc\n  }\n  return appliquer(f, valeurInitiale, [])\n}\n\nconst compteARebour = n =\u003e deplier((n) =\u003e {\n  return n \u003c= 0 ? undefined : [n, n - 1]\n}, n)\n\ncompteARebour(5) // [5, 4, 3, 2, 1]\n```\n\n__Pour aller plus loin__\n\n* [Anamorphisme](https://fr.wikipedia.org/wiki/Anamorphisme) sur Wikipédia\n\n### Hylomorphisme\n\nUn hylomorphisme (_hylomorphism_ en anglais) est une fonction récursive composée d’un [anamorphisme](#anamorphisme)\nsuivi d’un [catamorphisme](#catamorphisme).\n\n```js\nconst sommeJusquaX = (x) =\u003e somme(compteARebour(x))\nsommeJusquaX(5) // 15\n```\n\n__Pour aller plus loin__\n\n* [Hylomorphism (en)](https://en.wikipedia.org/wiki/Hylomorphism_(computer_science)) sur Wikipédia\n\n### Paramorphisme\n\nUn paramorphisme (_paramorphism_ en anglais) est une fonction similaire [`reduceRight`](#catamorphisme), bien qu’il y\nait une différence. Dans un paramorphisme, les arguments du réducteur sont la valeur actuelle, la réduction de toutes\nles valeurs précédentes et la liste des valeurs qui ont formé cette réduction.\n\n```js\n// Dangereux avec des listes contenant `undefined`, mais suffisant pour notre exemple.\nconst paramorphisme = (reducteur, accumulateur, elements) =\u003e {\n  if (elements.length === 0) { return accumulateur }\n\n  const premierElement = elements[0]\n  const autresElements = elements.slice(1)\n\n  return reducteur(premierElement, autresElements, paramorphisme(reducteur, accumulateur, autresElements))\n}\n\nconst suffixes = liste =\u003e paramorphisme(\n  (x, xs, suffxs) =\u003e [xs, ...suffxs],\n  [],\n  liste\n)\n\nsuffixes([1, 2, 3, 4, 5]) // [[2, 3, 4, 5], [3, 4, 5], [4, 5], [5], []]\n```\n\nLe troisième paramètre du réducteur (dans l’exemple ci-dessus, `[x, ... xs]`) donne une sorte d’historique de ce qui a\nconduit à la valeur `accumulateur` actuelle.\n\n__Pour aller plus loin__\n\n* [Paramorphism (en)](https://en.wikipedia.org/wiki/Paramorphism) sur Wikipédia\n\n### Apomorphisme\n\nL'apomorphisme (_apomorphism_ en anglais) est le contraire du paramorphisme, tout comme l’anamorphisme est celui du\ncatamorphisme. Avec le paramorphisme, l’accès à l’accumulateur et à ce qui a été accumulé sont conservés. L’apomorphisme\npermet de _déplier (`unfold`)_ et laisse la possibilité de retourner une valeur plus tôt.\n\n__Pour aller plus loin__\n\n* [Apomorphism (en)](https://en.wikipedia.org/wiki/Apomorphism) sur Wikipédia\n\n## Setoïde\n\nUn setoïde (_setoid_ en anglais) est un objet qui a une fonction `equals` qui peut être utilisée pour le comparer à\nd’autres objets du même type.\n\nPour faire de `array` un setoïde :\n\n```js\nArray.prototype.equals = function (arr) {\n  const taille = this.length\n  if (taille !== arr.length) {\n    return false\n  }\n  for (let i = 0; i \u003c taille; i++) {\n    if (this[i] !== arr[i]) {\n      return false\n    }\n  }\n  return true\n}\n\n;[1, 2].equals([1, 2]) // true\n;[1, 2].equals([0]) // false\n```\n\n## Demi-groupe\n\nUn demi-groupe (aussi appelé semi-groupe, ou _semigroup_ en anglais), est un objet doté d’une fonction `concat` qui\npermet de le combiner avec un autre objet du même type.\n\n```js\n;[1].concat([2]) // [1, 2]\n```\n\n__Pour aller plus loin__\n\n* [Demi-groupe](https://fr.wikipedia.org/wiki/Demi-groupe) sur Wikipédia\n\n## Foldable\n\nUn _foldable_ (terme anglais) est un objet doté d’une fonction `reduce` qui applique une fonction à un accumulateur et à\nchaque élément du tableau (de gauche à droite) pour le réduire à une seule valeur.\n\n```js\nconst somme = (liste) =\u003e liste.reduce((acc, val) =\u003e acc + val, 0)\nsomme([1, 2, 3]) // 6\n```\n\n## Lentille\n\nUne lentille (_lens_ en anglais) est une structure (souvent un objet ou une fonction) qui associe un _getter_ et un\n_setter_ non mutable et est utilisé sur d’autres structures.\n\n```js\n// En utilisant les [lentilles de Ramda (en)](https://ramdajs.com/docs/#lens)\nconst lentilleSurLeNom = R.lens(\n  // getter pour la propriété nom\n  (obj) =\u003e obj.nom,\n  // setter pour la propriété nom\n  (val, obj) =\u003e Object.assign({}, obj, { nom: val })\n)\n```\n\nLe fait d’avoir des accesseurs pour une structure donnée permet quelques fonctionnalités clés.\n\n```js\nconst personne = { nom: 'Gertrude Blanch' }\n\n// utilisation du getter\nR.view(lentilleNom, personne) // 'Gertrude Blanch'\n\n// utilisation du setter\nR.set(lentilleNom, 'Shafi Goldwasser', personne) // {nom: 'Shafi Goldwasser'}\n\n// applique la fonction `majuscule` sur la valeur de la structure\nR.over(lentilleNom, majuscule, personne) // {nom: 'GERTRUDE BLANCH'}\n```\n\nLes lentilles sont aussi composables. Cela permet d’effectuer facilement des mises à jour de données profondément\nimbriquées.\n\n```js\n// Cette lentille se concentre sur le premier élément d’un tableau non vide\nconst lentillePremierElement = R.lens(\n  // getter sur le premier élément du tableau\n  elements =\u003e elements[0],\n  // setter non mutable du premier élément du tableau\n  (val, [__, ...elements]) =\u003e [val, ...elements]\n)\n\nconst personnes = [{ nom: 'Gertrude Blanch' }, { nom: 'Shafi Goldwasser' }]\n\n// Malgré ce que vous pourriez supposer, les lentilles se composent de gauche à droite.\nR.over(compose(lentillePremierElement, lentilleNom), majuscule, personnes) // [{'nom': 'GERTRUDE BLANCH'}, {'nom': 'Shafi Goldwasser'}]\n```\n\nAutres implémentations :\n\n* [partial.lenses (en)](https://github.com/calmm-js/partial.lenses)\n* [nanoscope (en)](http://www.kovach.me/nanoscope/)\n\n## Signatures de type\n\nSouvent, les fonctions en JavaScript incluent des commentaires qui indiquent les types de leurs arguments et les valeurs\nde retour. C'est leur signature de type (_type signature_ en anglais).\n\nLes pratiques varient beaucoup au sein de la communauté, mais ils suivent souvent les modèles suivants :\n\n```js\n// nomFonction :: premierType -\u003e secondType -\u003e typeDeRetour\n\n// ajouter :: Number -\u003e Number -\u003e Number\nconst ajouter = (x) =\u003e (y) =\u003e x + y\n\n// incrementer :: Number -\u003e Number\nconst incrementer = (x) =\u003e x + 1\n```\n\nSi une fonction accepte une autre fonction comme argument, elle est placée entre parenthèses :\n\n```js\n// appeler :: (a -\u003e b) -\u003e a -\u003e b\nconst appeler = (f) =\u003e (x) =\u003e f(x)\n```\n\nLes lettres `a`, `b`, `c`, `d` sont utilisée pour signifier que l’argument peut être de n’importe quel type. La version\nsuivante de `map` prend une fonction qui transforme une valeur d’un type `a` en un autre type `b`, un tableau de valeurs\nde type `a`, et retourne un tableau de valeurs de type `b`.\n\n```js\n// map :: (a -\u003e b) -\u003e [a] -\u003e [b]\nconst map = (f) =\u003e (liste) =\u003e liste.map(f)\n```\n\n__Pour aller plus loin__\n\n* [Signature de type](https://fr.wikipedia.org/wiki/Signature_de_type) sur Wikipédia\n* [Ramda’s type signatures (en)](https://github.com/ramda/ramda/wiki/Type-Signatures)\n* [Mostly Adequate Guide (en)](https://drboolean.gitbooks.io/mostly-adequate-guide/content/ch7.html#whats-your-type)\n* [What is Hindley-Milner? (en)](http://stackoverflow.com/a/399392/22425) sur Stack Overflow\n\n## Type algébrique de données\n\nUn type algébrique de données (_algebraic data type_ en anglais) est un type composite fabriqué à partir de l’assemblage\nd’autres types. Deux classes communes de types algébriques sont les [sommes](#types-somme) et les\n[produits](#types-produit).\n\n__Pour aller plus loin__\n\n* [Type algébrique de données](https://fr.wikipedia.org/wiki/Type_alg%C3%A9brique_de_donn%C3%A9es) sur Wikipédia\n\n### Types somme\n\nUn type somme (_sum type_ en anglais) est l’union de deux types l’un avec l’autre. On l’appelle ainsi car le nombre de\nvaleurs possibles dans le type résultant est la somme des types d’entrée.\n\nJavaScript n’a pas de type somme, mais on peut néanmoins utiliser les `Set`s le simuler :\n\n```js\n// Imaginez que plutôt que des ensembles ici, nous avons des types qui ne peuvent prendre que ces valeurs.\nconst bools = new Set([true, false])\nconst halfTrue = new Set(['half-true'])\n\n// Le type LogiqueFaible contient la somme des valeurs de bools et halfTrue\nconst valeursDeLogiqueFaible = new Set([...bools, ...halfTrue])\n```\n\nLes types somme sont parfois appelés _types union_ (_union types_ en anglais), _unions discriminées_ (_discriminated\nunions_ en anglais) ou _unions étiquetées_ (_tagged unions_ en anglais).\n\nIl existe [plusieurs](https://github.com/paldepind/union-type) [bibliothèques](https://github.com/puffnfresh/daggy) en\nJavaScript qui facilitent la définition et l’utilisation des types somme.\n\nFlow défini [des types union](https://flow.org/en/docs/types/unions/) et TypeScript\n[des énumérations](https://www.typescriptlang.org/docs/handbook/enums.html) pour jouer ce rôle.\n\n__Pour aller plus loin__\n\n* [Type somme](https://fr.wikipedia.org/wiki/Type_alg%C3%A9brique_de_donn%C3%A9es#Type_somme) sur Wikipédia\n\n### Types produit\n\nUn type produit (_product type_ en anglais) combine des types d’une manière que vous connaissez probablement mieux :\n\n```js\n// point :: (Number, Number) -\u003e {x: Number, y: Number}\nconst point = (x, y) =\u003e ({ x, y })\n```\n\nL’exemple précédent est ce qu’on appelle un produit car l’ensemble des valeurs possibles de la structure de données est\nle produit des différentes valeurs. De nombreux languages ont un type tuple qui est la formulation la plus simple d’un\ntype produit.\n\n__Pour aller plus loin__\n\n* [Type produit](https://fr.wikipedia.org/wiki/Type_alg%C3%A9brique_de_donn%C3%A9es#Type_produit) sur Wikipédia\n* [Théorie des ensembles](https://fr.wikipedia.org/wiki/Th%C3%A9orie_des_ensembles) sur Wikipédia\n\n## Option\n\nL’option (terme identique en anglais) est un [type somme](#types-somme) qui encapsule deux cas souvent appelés\n`Some` et `None`. Les options sont utiles avec des fonctions qui peuvent ne pas renvoyer de valeur.\n\n```js\n// Définition naïve\n\nconst Some = (v) =\u003e ({\n  val: v,\n  map (f) {\n    return Some(f(this.val))\n  },\n  chain (f) {\n    return f(this.val)\n  }\n})\n\nconst None = () =\u003e ({\n  map (f) {\n    return this\n  },\n  chain (f) {\n    return this\n  }\n})\n\n// optionnel :: (String, {a}) -\u003e Option a\nconst optionnel = (key, obj) =\u003e typeof obj[key] === 'undefined' ? None() : Some(obj[key])\n```\n\nUtilisez `chain` pour enchaîner des fonctions qui retournent des `Option`s:\n\n```js\n\n// getArticle :: Panier -\u003e Option Article\nconst getArticle = (panier) =\u003e optionnel('article', panier)\n\n// getPrix :: Article -\u003e Option Number\nconst getPrix = (article) =\u003e optionnel('prix', article)\n\n// getPrixImbrique :: cart -\u003e Option a\nconst getPrixImbrique = (panier) =\u003e getArticle(panier).chain(getPrix)\n\ngetPrixImbrique({}) // None()\ngetPrixImbrique({ item: { foo: 1 } }) // None()\ngetPrixImbrique({ item: { price: 9.99 } }) // Some(9.99)\n```\n\n`Option` est aussi connu sous le nom `Maybe`. `Some` est parfois appelé `Just`, et `None` est parfois appelé `Nothing`.\n\n## Fonction\n\nEn programmation fonctionnelle, une fonction (ou expression lambda) `f :: A =\u003e B` est une expression avec un seul\nargument immuable de type `A`et une seule valeur de retour de type `B`. La valeur de retour dépend entièrement de\nl’argument, ce qui rend la fonction [référentiellement transparente](#transparence-référentielle). Cela implique donc\nque la fonction ne produit aucun [effet de bord](#effets-de-bord) caché et qu'elle est [pure](#fonction-pure) par\ndéfinition. Ces propriétés rendent les fonctions agréables à manipuler : elles sont complètement déterministes et ainsi\nprévisibles. Les fonctions permettent d’utiliser le code comme des données, en faisant abstraction du comportement :\n\n```js\n// fois2 :: Number -\u003e Number\nconst fois2 = n =\u003e n * 2\n\n;[1, 2, 3].map(fois2) // [2, 4, 6]\n```\n\n## Fonction partielle\n\nUne fonction partielle est une [function](#fonction) qui n’est pas définie pour tous les arguments - elle peut renvoyer\nun résultat inattendu ou ne jamais se terminer. Les fonctions partielles ajoutent de la surcharge cognitive, elles sont\nplus difficiles à appréhender et peuvent entraîner des erreurs d’exécution.\n\n```js\n// exemple 1 : somme d’une liste\n// somme :: [Number] -\u003e Number\nconst somme = nombres =\u003e nombres.reduce((a, b) =\u003e a + b)\nsomme([1, 2, 3]) // 6\nsomme([]) // TypeError: Reduce of empty array with no initial value\n\n// exemple 2 : récupération du premier élément d’une liste\n// premier :: [A] -\u003e A\nconst premier = a =\u003e a[0]\npremier([42]) // 42\npremier([]) // undefined\n// ou pire\npremier([[42]])[0] // 42\npremier([])[0] // Uncaught TypeError: Cannot read property '0' of undefined\n\n// exemple 3 : repéter une fonction N fois\n// repeter :: Number -\u003e (Number -\u003e Number) -\u003e Number\nconst repeter = n =\u003e fn =\u003e n \u0026\u0026 (fn(n), times(n - 1)(fn))\nrepeter(3)(console.log)\n// 3\n// 2\n// 1\nrepeter(-1)(console.log) // RangeError: Maximum call stack size exceeded\n```\n\n### Manipuler des fonctions partielles\n\nLes fonctions partielles sont dangereuses et doivent être utilisées avec prudence. Vous pouvez en effet obtenir un\nrésultat inattendu (erroné), rencontrer des erreurs d’exécution, ou même s’exécuter indéfiniment lorsque vous les\nutilisez. Connaitre et traiter tous ces cas aux limites peut donc devenir très fastidieux.\n\nHeureusement, il est possible de transformer une fonction partielle en fonction traditionnelle (ou fonction totale).\nOn peut en effet utiliser des valeurs par défaut ou des garde-fous pour traiter les entrées pour lesquelles la fonction\npartielle n’a pas de comportement défini. En utilisant par exemple le type [Option](#Option), nous pouvons obtenir\nsoit `Some(value)` ou `None` là où la fonction se serait comportée de manière inattendue.\n\n```js\n// exemple 1: somme d’une liste\n// on peut fournir une valeur par défaut afin que la fonction renvoie toujours un résultat\n// somme :: [Number] -\u003e Number\nconst somme = arr =\u003e arr.reduce((a, b) =\u003e a + b, 0)\nsomme([1, 2, 3]) // 6\nsomme([]) // 0\n\n// exemple 2: récupération du premier élément d’une liste\n// on peut utiliser le type Option\n// premier :: [A] -\u003e Option A\nconst premier = a =\u003e a.length ? Some(a[0]) : None()\npremier([42]).map(a =\u003e console.log(a)) // 42\npremier([]).map(a =\u003e console.log(a)) // console.log ne s’exécutera pas\n// et avec le pire scénario\npremier([[42]]).map(a =\u003e console.log(a[0])) // 42\npremier([]).map(a =\u003e console.log(a[0])) // console.log ne s’exécutera pas, et il n’y aura pas d’erreur\n// De plus, vous saurez grâce au type de retour (Option) que vous devez utiliser `.map`\n// pour accèder à la valeur de retour et vous n’oublierez plus de vérifier l’argument\n// car cela devient obligatoire.\n\n// exemple 3: repéter une fonction N fois\n// on fait en sorte que la fonction se termine toujours en changeant les conditions\n// repeter :: Number -\u003e (Number -\u003e Number) -\u003e Number\nconst repeter = n =\u003e fn =\u003e n \u003e 0 \u0026\u0026 (fn(n), times(n - 1)(fn))\nrepeter(3)(console.log)\n// 3\n// 2\n// 1\nrepeter(-1)(console.log) // ne fera rien\n```\n\nEn rendant vos fonctions partielles totales, les erreurs d’exécution peuvent être évités. Toujours renvoyer une valeur\npermet de plus d’obtenir du code qui est à la fois plus facile à comprendre et à maintenir.\n\n## Fonction totale\n\nUne fonction partielle est une [function](#fonction) qui renvoie un résultat valide pour toutes les valeurs d’entrées\npossibles. Les fonctions totales s’opposent aux [fonctions partielles](#fonction-partielle) qui peuvent générer des\nerreurs, renvoyer un résultat inattendu ou s’exécuter indéfiniment.\n\n## Bibliothèques de programmation fonctionnelle en JavaScript\n\n* [mori](https://github.com/swannodette/mori)\n* [Immutable](https://github.com/facebook/immutable-js/)\n* [Immer](https://github.com/mweststrate/immer)\n* [Ramda](https://github.com/ramda/ramda)\n* [ramda-adjunct](https://github.com/char0n/ramda-adjunct)\n* [ramda-extension](https://github.com/tommmyy/ramda-extension)\n* [Folktale](http://folktale.origamitower.com/)\n* [monet.js](https://cwmyers.github.io/monet.js/)\n* [lodash](https://github.com/lodash/lodash)\n* [Underscore.js](https://github.com/jashkenas/underscore)\n* [Lazy.js](https://github.com/dtao/lazy.js)\n* [maryamyriameliamurphies.js](https://github.com/sjsyrek/maryamyriameliamurphies.js)\n* [Haskell in ES6](https://github.com/casualjavascript/haskell-in-es6)\n* [Sanctuary](https://github.com/sanctuary-js/sanctuary)\n* [Crocks](https://github.com/evilsoft/crocks)\n* [Fluture](https://github.com/fluture-js/Fluture)\n* [fp-ts](https://github.com/gcanti/fp-ts)\n\n---\n\n__P.S.__ : Merci à toutes les personnes ayant contribué\n[au dépôt d’origine](https://github.com/hemanth/functional-programming-jargon/graphs/contributors) comme à\n[ce dépôt](https://github.com/marcwrobel/functional-programming-jargon-fr/graphs/contributors) !\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcwrobel%2Ffunctional-programming-jargon-fr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcwrobel%2Ffunctional-programming-jargon-fr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcwrobel%2Ffunctional-programming-jargon-fr/lists"}