Buscar..


Observaciones

¿Qué es la programación funcional?
Programación funcional o PF es un paradigma de programación que se basa en dos conceptos principales: inmutabilidad y apatridia . El objetivo detrás de la PF es hacer que su código sea más legible, reutilizable y portátil.

¿Qué es JavaScript funcional?
Ha habido un debate para llamar a JavaScript como un lenguaje funcional o no. Sin embargo, absolutamente podemos usar JavaScript como funcional debido a su naturaleza:

Los ejemplos deben cubrir cada concepto en detalle, y los enlaces que se proporcionan aquí son solo para referencia, y deben eliminarse una vez que se ilustra el concepto.

Aceptando funciones como argumentos

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]

Como puede ver, nuestra función de transform acepta dos parámetros, una función y una colección. A continuación, iterará la colección e insertará los valores en el resultado, llamando a fn en cada uno de ellos.

¿Luce familiar? ¡Esto es muy similar a cómo Array.prototype.map() funciona!

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

Funciones de orden superior

En general, las funciones que operan en otras funciones, ya sea tomándolas como argumentos o devolviéndolas (o ambas), se llaman funciones de orden superior.

Una función de orden superior es una función que puede tomar otra función como argumento. Está utilizando funciones de orden superior al pasar devoluciones de llamada.

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 función de orden superior es también una función que devuelve otra función como su resultado.

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

Mada de identidad

Este es un ejemplo de una implementación de la mónada de identidad en JavaScript y podría servir como punto de partida para crear otras mónadas.

Basado en la conferencia de Douglas Crockford sobre mónadas y gónadas.

El uso de este enfoque reutilizará sus funciones debido a la flexibilidad que proporciona esta mónada y las pesadillas de composición:

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

legible, agradable y limpio:

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

Funciona con valores primitivos.

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

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

Y tambien con objetos.

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'

Probemos todo:

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

Funciones puras

Un principio básico de la programación funcional es que evita cambiar el estado de la aplicación (sin estado) y las variables fuera de su alcance (inmutabilidad).

Las funciones puras son funciones que:

  • con una entrada dada, siempre devuelve la misma salida
  • No confían en ninguna variable fuera de su alcance.
  • no modifican el estado de la aplicación ( sin efectos secundarios )

Echemos un vistazo a algunos ejemplos:


Las funciones puras no deben cambiar ninguna variable fuera de su alcance.

Función 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 función cambió el valor obj.a que está fuera de su alcance.

Función 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 función no cambió los valores del objeto obj


Las funciones puras no deben depender de variables fuera de su alcance.

Función 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

Esta función impura se basa en la variable a que se define fuera de su alcance. Entonces, si se modifica a, el resultado de la función de impure será diferente.

Función 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

La pure 's resultado de la función no depende de ninguna variable fuera su alcance.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow