Privacy e cookie
Questo sito utilizza i cookie. Continuando, accetti il tuo uso. Ottieni maggiori informazioni; Ad esempio, su come controllare i cookie.
annunci
Torniamo alla serie Post dedicata alla programmazione funzionale in JavaScript. Abbiamo spiegato l’importanza dell’uso dei metodi incatenati per ottenere un codice più espressivo.
Nel post di oggi parleremo degli svantaggi che ci portano l’uso di metodi incatenati. Impareremo un nuovo modo di modulare il nostro codice e prendere molta più festa al riutilizzo del codice attraverso il concetto di tubi che possono essere utilizzati nella programmazione funzionale.
spiegheremo cosa siano i tubi e il Caratteristiche Abbiamo bisogno che soddisfino le funzioni per poter ottenere tale sensazione di codice che scorre per mezzo di un tubo collegato. Spiegheremo ciò che l’Arity è e il modo in cui i tocchi oi curricieri possono aiutarci a gestire la complessità degli alti autunni.
Come sempre, mi hai a tua disposizione nei commenti nel caso in cui potesse risolvere tutti i tuoi dubbi . Iniziamo:
Il problema dei metodi incatenati
i metodi incatenati ci aiutano molto a scrivere un codice migliore. Potremmo vederlo nel capitolo precedente. Che non cambia. Tuttavia, troviamo un grosso problema ai metodi incatenati.
Se ricordiamo, ad esempio, il metodo ‘Filtro’ di ES5, il metodo restituisce un nuovo oggetto Array che contiene nuovamente i metodi. Da qui la magia di essere in grado di concatenare. Sfortunatamente, il modello è un’arma a doppio taglio poiché i metodi sono così accoppiati al tipo di oggetto che li confina ci dà pochissima flessibilità del riutilizzo.
Con metodi concatenati siamo obbligati a utilizzare solo il set di operazioni che forniscono l’oggetto stesso. Sarebbe ideale che potremmo rompere questa catena e all’interno dell’assemblea potremmo organizzare funzioni nel nostro desiderio. I metodi incatenati non sono la soluzione, quindi dovremo cercarci un’altra alternativa.
I tubi
e l’alternativa arriva sotto forma di tubo. Se con i metodi incatenati abbiamo perso espressività e vincendo troppo accoppiamento, con l’organizzazione di funzioni in un tubo che potremmo avere il contrario.
La chiave per organizzare le funzioni nelle condotte è quella di poter avere un Arsenale delle funzioni disaccoppiati che possono essere eseguiti in sequenza. Come in un tubo, le nostre funzioni spendono gli stati di una funzione all’altra. I parametri di uscita di una funzione supportano i parametri di input del seguente.
In questo modo, posso creare pezzi di codice molto indipendenti, che rispettano una funzione specifica e che per composizione delle sue voci e delle loro partenze Può creare un programma importante.
Se usiamo la notazione utilizzata in Haskell, possiamo spiegare meglio questo. Possiamo definire le funzioni in questo modo:
<nombre_funcion> :: <entradas> -> <salidas>
Alla fine è molto simile alla definizione della Lambdas, solo in questo caso, siamo più interessati a sapere cosa Tipi di dati Inserisci e lasciano una funzione. È la specifica di una scatola nera.
L’ho visto, vediamo un esempio. Posso comporre per mezzo di condotte le seguenti funzioni:
f :: A -> Bg :: B -> C
Dove f e G sono il nome di una funzione e A, B e C sono tipi diversi. In questo caso, poiché l’output di F corrisponde al tipo di B. Potrei eseguirli come se fosse un tubo:
g(f(A)); // donde se devuelve C
Questo a prima vista sembra ovvio, puoi aiutarci molto. Non sarà facile ottenere questo in ambienti più complessi poiché ci saranno funzioni che restituiscano oggetti che non possono essere riutilizzati.
Tuttavia, è qualcosa che dobbiamo tenere in considerazione quando si progettano funzioni. È importante vedere che dobbiamo fare funzioni compatibili con l’altro. Alla consapevolezza di questo nel processo di progettazione, è importante considereremo due fattori: la compatibilità dei tipi di ingressi e uscite e l’aridazione delle funzioni.
Compatibilità del tipo
Come Abbiamo detto, la compatibilità del tipo si riferisce ai tipi di uscita della funzione relativi ai tipi dei parametri di input da un altro. Non è un problema che dobbiamo preoccupare molto in JavaScript perché alla fine quando si incontrano un linguaggio debolmente tipico, possiamo avere molta più flessibilità.
Alla fine questo è ciò che di solito è chiamato “tipi di anatra”, non sono interessato a tubi JavaScript così tanto che i tipi sono identici e che l’oggetto che restituisce una funzione, si comporta come il tipo di Il parametro di input in attesa della mia prossima funzione. Cioè, se va come un’anatra e grazna come un’anatra, è un’anatra. Se un oggetto si comporta un tipo specifico e ha gli attributi che mi aspetto in questo tipo, per me è quel ragazzo. È la cosa buona e la cosa brutta di JavaScript.
Se volessimo rendere le nostre funzioni rigorosamente compatibili, una buona idea sarebbe quella di utilizzare dattiloscritto. Lascio di nuovo la chat di Micael Galiziano qui nel caso in cui ti interessa questa alternativa.
Pertanto, quando progettiamo funzioni, dobbiamo avere molto chiara i ragazzi con cui le nostre funzioni giocano. Immagina che vogliamo creare un sistema che ha dato un numero di identità, rimuoviamo gli spazi e gli script per lavorare meglio con esso. Progetteremo due funzioni come queste:
trim :: String -> Stringnormalize :: String -> String
Abbiamo creato due funzioni compatibili per la composizione poiché l’ingresso di una corrisponde il tipo dell’altro. Sono anche commutativi perché se eseguono finiture e poi normalizzando, ottengo lo stesso risultato di come se fossi prima “normalizzarsi” e poi “Trim”. Vediamo l’implementazione.
Vale, l’esempio è molto sciocco, ma è importante che ci consapevoli in futuro. Avremo più problemi in JavaScript con il numero di parametri che possono consentire una funzione.
L’ARITA e TUPILI
Sappiamo per ARITY al numero di parametri di input che accettano una funzione . È comune indicarlo come una lunghezza di una funzione.
L’Arità di una funzione può far vincere una funzione in complessità. Che una funzione accetta diversi parametri rendono innanzitutto tutti gli argomenti, questo li rende perdono la versatilità.
Inoltre, può essere il caso che la complessità interna di una funzione sia maggiore (che è una grande aria Non sempre si comporta una complessità più alta, può semplicemente essere un sintomo di esso).
Avere forniture elevate in aggiunta, ci fa avere funzioni meno flessibili. Le funzioni con un parametro (o protolori) sono in genere più flessibili perché, in generale, hanno solo una singola responsabilità, eseguire un certo tipo di operazione o calcola il parametro di input e restituire il risultato.
Sfortunatamente, Nella vita reale è complicato soddisfare solo gli urti. Tuttavia, possiamo effettuare una funzione restituisce una tupla, in questo modo la prossima funzione sarebbe un Arry e avrei già tutto lo stato di cui hai bisogno.
A TUPLA è un elenco finito e ordinato dei valori Che sono rappresentati come segue (A, B, C). Le tuple sono un pacchetto di valori immutabili, che hanno una relazione e che possono essere utilizzati per restituire diversi valori ad altre funzioni.
Possiamo simulare questo comportamento con un oggetto JSON o con oggetti array, non appena presto Come vediamo poi con le tuple abbiamo più vantaggi:
- è immutabile.
- Evita la creazione di nuovi tipi. Molte volte per creare classi per un singolo uso specifico può essere abbastanza economico per lo sviluppatore.
- Evita di creare array eterogenei: lavorare con questi array eterogenei suppone un sacco di sviluppo di controlli di tipo. Gli array sono meglio semplicemente usarli quando si lavora con collezioni di oggetti con lo stesso tipo.
Il problema che abbiamo, è che sebbene la tupes sia un elemento nella maggior parte dei linguaggi di programmazione funzionali come Scala, in JavaScript Non c’è nulla che supporti le tuple. L’opzione migliore per questo è che crediamo a una piccola libreria che supporti Tuples. L’opzione che l’attenzione che Luis si propone nel tuo libro è questa:
const Tuple = function () { const typeInfo = Array.prototype.slice.call(arguments, 0); const _T = function () { const values = Array.prototype.slice.call(arguments, 0); if (values.some((val) => val === null || val === undefined) { throw new ReferenceError('Tuples may not have any null values'); } if (values.length !== typeInfo.length) { throw new TypeErro('Tuple arity does not match its prototype'); } values.map(function (val, index) { this = checkType(typeInfo)(val); }, this); Object.freeze(this); }; _T.prototype.values = function () { return Object.keys(this).map(function (k) { return this; } } return _T;}
UF, sì, un sacco di chicha da tagliare. Se ci rendiamo conto è una funzione tupla che restituirà una classe. La funzione serve in modo che possiamo indicare le dimensioni e i tipi degli elementi del TUPLA. Pertanto, possiamo farlo, ad esempio:
const Status = Tuple(Number, String);
‘Stato’ è una classe. Se ti dai tuble, sta tornando _t. Per mezzo di un clouser, una classe preconfigurata viene restituita con ciò di cui abbiamo bisogno. Magico. Ora possiamo definire una nuova tupla in questo modo:
const status = new Status(401, 'No Authorize');
Quando istanziata ‘stato’ è un controllo che i valori nullo non stiano accadendo e questo La dimensione della tupla creata corrisponde alle dimensioni del tupla predefinito. Verifica inoltre che il tipo che è accaduto è previsto.
Infine, ha un metodo in modo che possiamo ottenere i valori in formato array.È molto utile perché se usiamo di nuovo la distruggente, possiamo ottenere i valori del tupi in questo modo:
const = status.values();
buono … loro Non sono i più comodi delle tuple del mondo in JavaScript, ma abbiamo modi per simularlo. Cosa succede se non dovessimo simularli? Cosa succede se JS e in serie li porti? Bene, di nuovo, i dattiloscritti ci aiuta in questo. Potrei farlo:
let status: ; status = ; // OK status = ; // Error
molto meglio :). Ripeto, tieni presente dattiloscritto, è arrivato a stare.
Tuples sono un buon meccanismo per evitare l’arresto delle funzioni. Tuttavia, c’è un altro metodo chiamato curricaly, che non solo ci aiuterà con l’areità, ma è un buon meccanismo migliorare la modularità e la riusabilità, ma … penso che andremo qui per oggi 🙂
Conclusione
Comprensione dei tubi e dei loro modi per usarli, ci aiuterà a sviluppare un codice più leggibile. Continueremo a parlare delle tecniche necessarie per coprire tutti i concetti che sono presenti nei tubi.
Per ora, penso che sia un buon passo sapendo che le funzioni di progettazione in modo da avere una ridotta areità e conoscere il Tipi dai parametri di input e output delle nostre funzioni, ci aiuteremo a creare un codice molto più manutenibile, modularilizzabile e riutilizzabile.
Leggi 🙂
PD: Lascio il concettuale Mappa di questa voce:
Precedente JavaScript Functional Programming Posts:
INTRODUZIONE
- Programmazione funzionale in JavaScript
- Programmazione funzionale in JavaScript: gli oggetti
- funzionali Programmazione in JavaScript: Funzioni
Controllo del flusso funzionale
- Programmazione funzionale in JavaScript: Metodi funzionali
- Programmazione funzionale in JavaScript: il RECURUZIONE
Modularità funzionale
- Programmazione funzionale in JavaScript: ARITY e Tuples
- Programmazione funzionale in JavaScript: il curricaly
Immagine di copertura | Flickr