(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-5LHNRP9'); thecodest, Autor en The Codest - Página 8 de 13

Introducción

A menudo, es difícil mantener lo inmodificable. El patrón de envolver datos en un contenedor viene al rescate. Asegura los valores para que manipularlos sea seguro con exclusión de efectos secundarios.

Si eres nuevo aquí asegúrate de revisar mis últimas 2 partes sobre programación funcional en The Codest blog sobre:

Functor

No tiene una lógica compleja. Su tarea principal es envolver el contexto y realizar sobre él las funciones que recibe del exterior. Cada vez que cambia el valor, se vuelve a empaquetar una nueva instancia del contenedor y se devuelve. Cuando se llama al mapa que toma una acción específica, devuelve una nueva instancia de contenedor con el valor devuelto por la función pasada, manteniendo el principio de no modificabilidad.

Declaración

 const Functor = valor => ({
     mapa: fn => Functor(fn(valor)),
     cadena: fn => fn(valor),
     de: () => valor
 });

mapa - útil cuando quieres cambiar el estado de un valor en un contenedor pero no quieres devolverlo todavía.

cadena - se utiliza si se desea pasar un valor a una función sin modificar el estado del contenedor. Suele ir al final de mapa llamadas.

de - devolver valor actual

Ejemplo imperativo

const randomInt = (max) => Math.floor(Math.random() * (max + 1))

const randomNumber = randomInt(200) // devuelve un número entre 0 y 200

decrease(randomNumber) // devuelve (número entre 0 y 200) - 1

Ejemplo declarativo

const randomIntWrapper = (max) =>
Functor(max)
.map(incremento) // max + 1
.map(multiplicarPor(Math.aleatorio())) // Math.random() * (max + 1)
.map(Math.floor) // Math.floor(Math.random() * (max + 1))

const randomNumber = randomIntWrapper(200)

randomNumber.of() // devuelve un número entre 0 y 200
randomNumber.chain(decrease) // devuelve (número entre 0 y 200) - 1

Mónada

A veces, además de las funciones que activan el nuevo estado del valor, necesitas lógica adicional oculta en el contenedor. Aquí es donde mónada es muy útil, ya que es una extensión de functor. Puede, por ejemplo, decidir qué debe ocurrir cuando el valor tiene un valor determinado o qué camino deben seguir las siguientes acciones.

Mónada Tal vez

La mónada quizás resuelve el problema de los valores que devuelven no verdadero. Cuando esto ocurre, las subsiguientes mapa se ignoran, pero permite devolver una alternativa llamando a la función getOr método. Le permite evitar el uso de operadores if / else, que son populares en imperativo programación. Esta mónada consta de tres contenedores:

Nada - se ejecuta cuando un valor que no es verdadero cae en el contenedor o filtro devuelve false. Se utiliza para simular la ejecución de una función. Esto significa que este contenedor recibe la función pero no la ejecuta.

Sólo - este es el contenedor principal que realiza todas las funciones, pero si el valor cambia a un valor falso o filtro devuelve false, lo pasará al método Nada contenedor.

Tal vez - Tomo el valor inicial y decido qué contenedor llamar al principio.

Declaración

const Just = valor => ({
mapa: fn => Maybe(fn(valor)),
cadena: fn => fn(valor),
de: () => valor,
getOr: () => valor,
filtro: fn => fn(valor) ? Sólo(valor) : Nada(),
tipo: 'just'
});

const Nada = () => ({
mapa: fn => Nada(),
cadena: fn => fn(),
de: () => Nada(),
getOr: sustituto => sustituto,
filtro: () => Nothing(),
tipo: 'nada
});

const Maybe = valor =>
value === null || value === undefined || value.type === 'nada'
? Nada()
: Just(valor)
tabla métodos functor

Ahora vamos a construir el ejemplo anterior sobre la condición. Si max es mayor que cero, la función se ejecutará. En caso contrario, devolverá 0.

Ejemplo imperativo

const randomInt = (max) => {
if(max > 0) {
return Math.floor(Math.random() * (max + 1))
} else {
return 0
}
}

const bookMiddlePage = 200

const randomPage = randomInt(10) || bookMiddlePage // devuelve random
const randomPage = randomInt(-10) || bookMiddlePage // devuelve 200

Ejemplo declarativo

const randomIntWrapper = (max) =>
Maybe(max)
.filter(max => max > 0) // valor false ignora llamadas posteriores
.map(incremento)
.map(multiplicarPor(Math.aleatorio()))
.map(Math.floor)

const libroPáginaIntermedia = 200

// Sólo contenedor
const randomPage = randomIntWrapper(10).getOr(bookMiddlePage) // devuelve aleatorio
// Contenedor nada
const randomPage = randomIntWrapper(-10).getOr(bookMiddlePage) // devuelve 200


bandera de cooperación

es_ESSpanish