Greitas įvadas į „pipe“ () ir „compos“ () „JavaScript“

Funkcinis programavimas man buvo gana atveriantis akį. Šis įrašas ir panašūs į jį yra bandymai pasidalinti savo įžvalgomis ir perspektyvomis, kai keliauju po naujus funkcinius programavimo laukus.

„Ramda“ buvo mano „FP“ biblioteka, nes tai labai palengvina funkcinį „JavaScript“ programavimą. Aš labai rekomenduoju.

Vamzdis

Sąvoka pipeyra paprasta - ji sujungia nfunkcijas. Tai vamzdis, tekantis iš kairės į dešinę, kiekvieną funkciją iškviečiantis paskutinės išvestimi.

Parašykime funkciją, kuri grąžina kieno nors funkciją name.

getName = (person) => person.name; getName({ name: 'Buckethead' }); // 'Buckethead' 

Parašykime funkciją, kuri didžiosiomis raidėmis rašo eilutes.

uppercase = (string) => string.toUpperCase(); uppercase('Buckethead'); // 'BUCKETHEAD' 

Taigi, jei norėtume gauti ir rašyti didžiosiomis raidėmis person, galėtume tai padaryti:

name = getName({ name: 'Buckethead' }); uppercase(name); // 'BUCKETHEAD' 

Puiku, bet pašalinkime tą tarpinį kintamąjį name.

uppercase(getName({ name: 'Buckethead' })); 

Geriau, bet aš nemėgstu to lizdo. Tai gali būti per daug žmonių. Ką daryti, jei norime pridėti funkciją, kuri gauna pirmuosius 6 eilutės simbolius?

get6Characters = (string) => string.substring(0, 6); get6Characters('Buckethead'); // 'Bucket' 

Rezultatas:

get6Characters(uppercase(getName({ name: 'Buckethead' }))); // 'BUCKET'; 

Išprotėkime ir pridėkime funkciją, kad pakeistume stygas.

reverse = (string) => string .split('') .reverse() .join(''); reverse('Buckethead'); // 'daehtekcuB' 

Dabar mes turime:

reverse(get6Characters(uppercase(getName({ name: 'Buckethead' })))); // 'TEKCUB' 

Tai gali gauti šiek tiek ... daug.

Vamzdis gelbėti!

Užuot trukdžius funkcijoms funkcijose ar sukūrus daugybę tarpinių kintamųjų, leiskime pipeviską!

pipe( getName, uppercase, get6Characters, reverse )({ name: 'Buckethead' }); // 'TEKCUB' 

Grynas menas. Tai tarsi Todo sąrašas!

Žingsniuokime pro jį.

Demonstraciniais tikslais naudosiu pipeįgyvendinimą iš vieno iš Erico Elliotto funkcinių programavimo straipsnių.

pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x); 

Aš myliu šį mažą pamušalą.

Naudodami poilsio parametrus, žr. Mano straipsnį apie tai, mes galime atlikti nfunkcijas. Kiekviena funkcija ima ankstesnės išvestį ir visa tai sumažėja ? į vieną vertę.

Ir jūs galite jį naudoti taip, kaip mes darėme aukščiau.

pipe( getName, uppercase, get6Characters, reverse )({ name: 'Buckethead' }); // 'TEKCUB' 

Išplėsiu pipeir pridėsiu kelis derintuvo teiginius ir eisime eilute.

pipe = (...functions) => (value) => { debugger; return functions.reduce((currentValue, currentFunction) => { debugger; return currentFunction(currentValue); }, value); }; 

Paskambinkite pipemūsų pavyzdžiu ir leiskite stebuklams atsiskleisti.

Patikrinkite vietinius kintamuosius. functionsyra 4 funkcijų masyvas ir valueyra { name: 'Buckethead' }.

Kadangi mes naudojome poilsio parametrus, pipeleidžia naudoti bet kokį skaičių funkcijų. Tai tiesiog kilpa ir paskambins kiekvienam.

Kitame derintuve mes viduje reduce. Čia currentValueperduodama currentFunctionir grąžinama.

Matome, kad rezultatas yra 'Buckethead'todėl, kad currentFunctiongrąžina .namebet kokio objekto savybę. Tai bus grąžinta reduce, vadinasi, currentValuekitą kartą tai taps nauju . Pataikykime kitam derintojui ir pamatysime.

Dabar currentValuetaip yra ‘Buckethead’todėl, kad būtent tai ir sugrįžo paskutinį kartą. currentFunctionyra uppercase, taip 'BUCKETHEAD'bus ir kitas currentValue.

Ta pati mintis: nuplėškite ‘BUCKETHEAD’pirmuosius 6 simbolius ir atiduokite juos kitai funkcijai.

reverse(‘.aedi emaS’)

Ir jūs baigėte!

O kūrinys ()?

Viskas tik pipekita linkme.

Taigi, jei norėtumėte to paties rezultato, kaip ir pipeaukščiau, atliktumėte priešingai.

compose( reverse, get6Characters, uppercase, getName )({ name: 'Buckethead' }); 

Atkreipkite dėmesį į tai, kaip getNameyra paskutinė grandinėje ir reversekas pirma?

Čia yra greitas įgyvendinimas compose, dar kartą sutinkant su stebuklingu Ericu Elliottu iš to paties straipsnio.

compose = (...fns) => (x) => fns.reduceRight((v, f) => f(v), x); 

Paliksiu jums išplėsti šią funkciją naudodamas debuggers. Žaisk su juo, naudokis, vertink. O svarbiausia - linksminkis!