Zoeken…


Opmerkingen

Wat is functioneel programmeren?
Functioneel programmeren of FP is een programmeerparadigma dat is gebaseerd op twee hoofdconcepten onveranderbaarheid en staatloosheid . Het doel achter FP is om uw code leesbaarder, herbruikbaar en draagbaar te maken.

Wat is functionele JavaScript
Er is een debat gaande om JavaScript een functionele taal te noemen of niet, maar we kunnen JavaScript absoluut als functioneel gebruiken vanwege zijn aard:

De voorbeelden moeten elk concept in detail behandelen, en de links die hier worden gegeven, zijn alleen voor referentie en moeten worden verwijderd zodra het concept is geïllustreerd.

Functies accepteren als argumenten

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]

Zoals u ziet, accepteert onze transform twee parameters, een functie en een verzameling. Het zal dan de verzameling herhalen en waarden naar het resultaat pushen, waarbij fn op elk van hen wordt fn .

Komt me bekend voor? Dit lijkt erg op hoe Array.prototype.map() werkt!

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

Hogere-orde functies

Over het algemeen worden functies die op andere functies werken, door ze als argumenten te nemen of door ze terug te geven (of beide), functies van een hogere orde genoemd.

Een hogere orde functie is een functie die een andere functie als argument kan nemen. U gebruikt functies van een hogere orde wanneer u callbacks doorgeeft.

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

Een hogere orde functie is ook een functie die als resultaat een andere functie retourneert.

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

Identiteit Monad

Dit is een voorbeeld van een implementatie van de identiteitsmonade in JavaScript en kan als startpunt dienen om andere monaden te maken.

Gebaseerd op de conferentie van Douglas Crockford over monaden en geslachtsklieren

Het gebruik van deze benadering zal het hergebruiken van uw functies gemakkelijker maken vanwege de flexibiliteit die deze monade biedt en nachtmerries over de compositie:

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

leesbaar, mooi en schoon:

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

Het werkt met primitieve waarden

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

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

En ook met objecten

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'

Laten we alles proberen:

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 functies

Een basisprincipe van functioneel programmeren is dat het voorkomt dat de applicatiestatus (staatloosheid) en variabelen buiten zijn bereik (onveranderlijkheid) worden gewijzigd .

Pure functies zijn functies die:

  • retourneer bij een gegeven invoer altijd dezelfde uitvoer
  • ze vertrouwen niet op een variabele buiten hun bereik
  • ze veranderen de status van de applicatie niet ( geen bijwerkingen )

Laten we een paar voorbeelden bekijken:


Pure functies mogen geen variabele buiten hun bereik veranderen

Onzuivere functie

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

De functie heeft de obj.a waarde gewijzigd die buiten het bereik valt.

Pure functie

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

De functie heeft de object obj waarden niet gewijzigd


Pure functies mogen niet afhankelijk zijn van variabelen die buiten hun bereik vallen

Onzuivere functie

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

Deze onzuivere functie is afhankelijk van variabele a die buiten zijn bereik wordt gedefinieerd. Dus als a wordt gewijzigd, zal het functieresultaat van impure anders zijn.

Pure functie

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

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

Het functieresultaat van de pure is niet afhankelijk van een variabele buiten zijn bereik.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow