Ricerca…


Osservazioni

Che cos'è la programmazione funzionale?
La programmazione funzionale o FP è un paradigma di programmazione basato su due concetti principali di immutabilità e apolidia . L'obiettivo di FP è rendere il codice più leggibile, riutilizzabile e portatile.

Cos'è il JavaScript funzionale
C'è stato un dibattito per chiamare JavaScript un linguaggio funzionale o no. Tuttavia, possiamo assolutamente usare JavaScript come funzionale per la sua natura:

Gli esempi dovrebbero riguardare ogni concetto in dettaglio, ei collegamenti forniti qui sono solo per riferimento e dovrebbero essere rimossi una volta che il concetto è illustrato.

Accettare le funzioni come argomenti

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]

Come puoi vedere, la nostra funzione di transform accetta due parametri, una funzione e una collezione. Quindi eseguirà l'iterazione della raccolta e sposterà i valori sul risultato, chiamando fn su ciascuno di essi.

Sembra familiare? Questo è molto simile a come funziona Array.prototype.map() !

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

Funzioni di ordine superiore

In generale, le funzioni che operano su altre funzioni, assumendole come argomenti o restituendole (o entrambe), sono chiamate funzioni di ordine superiore.

Una funzione di ordine superiore è una funzione che può assumere un'altra funzione come argomento. Stai utilizzando le funzioni di ordine superiore durante il passaggio di callback.

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);

Una funzione di ordine superiore è anche una funzione che restituisce un'altra funzione come risultato.

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()();

Identity Monad

Questo è un esempio di implementazione della monade dell'identità in JavaScript e potrebbe servire come punto di partenza per creare altre monadi.

Basato sulla conferenza di Douglas Crockford su monadi e gonadi

Utilizzando questo approccio riutilizzare le tue funzioni sarà più facile grazie alla flessibilità offerta da questa monade e agli incubi della composizione:

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

leggibile, bello e pulito:

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;
};

Funziona con valori primitivi

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

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

E anche con gli oggetti

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'

Proviamo tutto:

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

Pure funzioni

Un principio di base della programmazione funzionale è che evita di modificare lo stato dell'applicazione (apolidia) e le variabili al di fuori del suo ambito (immutabilità).

Le funzioni pure sono funzioni che:

  • con un dato input, restituisce sempre lo stesso output
  • non si basano su alcuna variabile al di fuori del loro scopo
  • non modificano lo stato dell'applicazione ( senza effetti collaterali )

Diamo un'occhiata ad alcuni esempi:


Le funzioni pure non devono modificare alcuna variabile al di fuori del loro ambito

Funzione impura

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 funzione ha cambiato il valore obj.a al di fuori del suo ambito.

Funzione pura

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 funzione non ha modificato i valori obj obiettivo


Le funzioni pure non devono basarsi su variabili al di fuori del loro ambito

Funzione impura

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

Questa funzione impura si basa sulla variabile a che è definita al di fuori del suo ambito. Quindi, se a viene modificato, il risultato della funzione impure sarà diverso.

Funzione pura

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

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

Il risultato della funzione pure non si basa su alcuna variabile al di fuori del suo ambito.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow