Recherche…


Remarques

Qu'est-ce que la programmation fonctionnelle?
La programmation fonctionnelle ou PF est un paradigme de programmation qui repose sur deux concepts principaux: l' immuabilité et l' apatridie . Le but de la PF est de rendre votre code plus lisible, réutilisable et portable.

Qu'est-ce que le JavaScript fonctionnel?
Il y a eu un débat pour appeler JavaScript un langage fonctionnel ou non. Cependant, nous pouvons absolument utiliser JavaScript comme une fonctionnalité en raison de sa nature:

Les exemples doivent couvrir chaque concept en détail, et les liens fournis ici sont fournis à titre de référence et doivent être supprimés une fois le concept illustré.

Accepter des fonctions comme arguments

function transform(fn, arr) {
    let result = [];
    for (let el of arr) {
        result.push(fn(el)); // We push the result of the transformed item to result
    }
    return result;
}

console.log(transform(x => x * 2, [1,2,3,4])); // [2, 4, 6, 8]

Comme vous pouvez le voir, notre fonction de transform accepte deux paramètres, une fonction et une collection. Il va ensuite itérer la collection, et pousser les valeurs sur le résultat, appelant fn sur chacun d'eux.

Semble familier? Ceci est très similaire à la façon dont Array.prototype.map() fonctionne!

console.log([1, 2, 3, 4].map(x => x * 2)); // [2, 4, 6, 8]

Fonctions d'ordre supérieur

En général, les fonctions qui opèrent sur d’autres fonctions, en les prenant comme arguments ou en les retournant (ou les deux), sont appelées fonctions d’ordre supérieur.

Une fonction d'ordre supérieur est une fonction qui peut prendre une autre fonction en argument. Vous utilisez des fonctions d'ordre supérieur lors du passage de rappels.

function iAmCallbackFunction() {
    console.log("callback has been invoked");
}

function iAmJustFunction(callbackFn) {
    // do some stuff ...

    // invoke the callback function.
    callbackFn();
}

// invoke your higher-order function with a callback function.
iAmJustFunction(iAmCallbackFunction);

Une fonction d'ordre supérieur est également une fonction qui renvoie une autre fonction en tant que résultat.

function iAmJustFunction() {
    // do some stuff ...

    // return a function.
    return function iAmReturnedFunction() {
        console.log("returned function has been invoked");
    }
}

// invoke your higher-order function and its returned function.
iAmJustFunction()();

Identité Monad

Ceci est un exemple d'implémentation de la monade d'identité en JavaScript et pourrait servir de point de départ pour créer d'autres monades.

Basé sur la conférence de Douglas Crockford sur les monades et les gonades

En utilisant cette approche, il sera plus facile de réutiliser vos fonctions grâce à la flexibilité offerte par cette monade et aux cauchemars de composition:

f(g(h(i(j(k(value), j1), i2), h1, h2), g1, g2), f1, f2)

lisible, agréable et propre:

identityMonad(value)
    .bind(k)
    .bind(j, j1, j2)
    .bind(i, i2)
    .bind(h, h1, h2)
    .bind(g, g1, g2)
    .bind(f, f1, f2);

function identityMonad(value) {
    var monad = Object.create(null);
    
    // func should return a monad
    monad.bind = function (func, ...args) {
        return func(value, ...args);
    };

    // whatever func does, we get our monad back
    monad.call = function (func, ...args) {
        func(value, ...args);

        return identityMonad(value);
    };
    
    // func doesn't have to know anything about monads
    monad.apply = function (func, ...args) {
        return identityMonad(func(value, ...args));
    };

    // Get the value wrapped in this monad
    monad.value = function () {
        return value;
    };
    
    return monad;
};

Il fonctionne avec des valeurs primitives

var value = 'foo',
    f = x => x + ' changed',
    g = x => x + ' again';

identityMonad(value)
    .apply(f)
    .apply(g)
    .bind(alert); // Alerts 'foo changed again'

Et aussi avec des objets

var value = { foo: 'foo' },
    f = x => identityMonad(Object.assign(x, { foo: 'bar' })),
    g = x => Object.assign(x, { bar: 'foo' }),
    h = x => console.log('foo: ' + x.foo + ', bar: ' + x.bar);

identityMonad(value)
    .bind(f)
    .apply(g)
    .bind(h); // Logs 'foo: bar, bar: foo'

Essayons tout:

var add = (x, ...args) => x + args.reduce((r, n) => r + n, 0),
    multiply = (x, ...args) => x * args.reduce((r, n) => r * n, 1),
    divideMonad = (x, ...args) => identityMonad(x / multiply(...args)),
    log = x => console.log(x),
    substract = (x, ...args) => x - add(...args);

identityMonad(100)
    .apply(add, 10, 29, 13)
    .apply(multiply, 2)
    .bind(divideMonad, 2)
    .apply(substract, 67, 34)
    .apply(multiply, 1239)
    .bind(divideMonad, 20, 54, 2)
    .apply(Math.round)
    .call(log); // Logs 29

Fonctions pures

Un principe de base de la programmation fonctionnelle est qu’elle évite de changer l’état de l’application (état d’apatridie) et les variables en dehors de sa portée (immuabilité).

Les fonctions pures sont des fonctions qui:

  • avec une entrée donnée, retourne toujours la même sortie
  • ils ne s'appuient sur aucune variable en dehors de leur champ d'application
  • ils ne modifient pas l'état de l'application ( pas d'effets secondaires )

Jetons un coup d'oeil à quelques exemples:


Les fonctions pures ne doivent changer aucune variable en dehors de leur portée

Fonction impure

let obj = { a: 0 }

const impure = (input) => {
  // Modifies input.a
  input.a = input.a + 1;
  return input.a;
}

let b = impure(obj)
console.log(obj) // Logs { "a": 1 }
console.log(b) // Logs 1

La fonction a modifié la valeur obj.a qui est hors de sa portée.

Fonction pure

let obj = { a: 0 }

const pure = (input) => {
  // Does not modify obj
  let output = input.a + 1;
  return output;
}

let b = pure(obj)
console.log(obj) // Logs { "a": 0 }
console.log(b) // Logs 1

La fonction n'a pas changé les valeurs d' obj objet


Les fonctions pures ne doivent pas s'appuyer sur des variables hors de leur portée

Fonction impure

let a = 1;

let impure = (input) => {
  // Multiply with variable outside function scope
  let output = input * a;
  return output;
}

console.log(impure(2)) // Logs 2
a++; // a becomes equal to 2
console.log(impure(2)) // Logs 4

Cette fonction impure repose sur la variable a définie en dehors de sa portée. Donc, si un est modifié, le résultat de la fonction impure sera différent.

Fonction pure

let pure = (input) => {
  let a = 1;
  // Multiply with variable inside function scope
  let output = input * a;
  return output;
}

console.log(pure(2)) // Logs 2

Le résultat de la fonction pure ne repose sur aucune variable en dehors de sa portée.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow