Programmazione funzionale in JavaScript Parte 2 - Combinatori
Pawel Ged
Sviluppatore Vue.js
Questa è la seconda parte della nostra serie di articoli dedicati alla potenza della programmazione funzionale in JavaScript. Consultate questo articolo per approfondire le vostre conoscenze sui combinatori.
Introduzione ai combinatori
I combinatori sono funzioni di livello superiore che consentono di combinare funzioni, variabili o altri combinatori. Di solito, non contengono dichiarazioni delle proprie variabili o della logica aziendale. Sono gli unici che permettono di controllare il controllo in un programma di funzioni.
In questo articolo cercherò di trattarne alcuni:
Rubinetto
Arricciatura
Tubo/Comporre
Forcella
Alternanza
Sequenza
Rubinetto
Un combinatore è molto utile per le funzioni che non restituiscono nulla. Prende la funzione a cui va il parametro e poi la restituisce.
Dichiarazione
const tap = (fn) => (valore) => {
fn(valore);
restituisce il valore;
};
Esempio di imperativo
const [items, setItems] = useState(() => [])
axios
.get('http://localhost')
.then({dati } => {
setItems(dati)
console.log(dati)
onLoadData(dati)
}).then(...) // restituisce undefined - i dati nella promessa sono stati modificati
Esempio dichiarativo
const [items, setItems] = useState(() => [])
axios
.get('http://localhost')
.then(({dati }) => dati)
.then(tap(setItems)) // (data) => { setItems(data); return data }
.then(tap(console.log)) // un then = una funzione = una responsabilità
.then(tap(onLoadData))
.then(...) // ancora accesso ai dati originali
// facile mantenere il principio di apertura/chiusura
Arricciatura
Divide gli argomenti di una funzione e permette di chiamarli in sequenza.
const somma = (a, b, c) => a + b + c
const currySum = curry(sum)
/*
possibili chiamate
currySum(a)(b)(c),
currySum(a)(b,c),
currySum(a,b)(c),
currySum(a,b,c)
*/
currySum(1) // (b, c) => 1 + a + b o (b) => (c) => 1 + a + b
currySum(5)(10) // (c) => 5 + 10 + b
currySum(5, 10) // (c) => 5 + 10 + b
currySum(5)(10)(20) // 35
currySum(5, 10)(20) // 35
currySum(5)(10, 20) // 35
const divideBy = curry((a, b) => b / a)
const multiplyBy = curry((a, b) => a * b)
const divideByTwo = divideBy(2)
divideByTwo(10) // restituisce 5
const multiplyByFive = multiplyBy(5)
multiplyByFive(10) // restituisce 50
Tubo/Comporre
Attraverso la composizione, è possibile passare i dati da una funzione all'altra. È importante che le funzioni accettino lo stesso numero di argomenti. La differenza tra pipe e compose è che la prima esegue le funzioni dalla prima all'ultima, mentre compose le chiama dalla fine.