Бързо въведение към pipe () и compose () в JavaScript

Функционалното програмиране беше доста атрактивното пътуване за мен. Тази публикация и публикации като нея са опит за споделяне на моите разбирания и перспективи, докато преследвам нови функционални програми.

Ramda ми беше библиотека с FP, тъй като много по-лесно прави функционалното програмиране в JavaScript. Горещо го препоръчвам.

Съставяне на блокове за образуване на структура. Доста дълбоки неща ...

Тръба

Концепцията на тръбата е проста - тя съчетава n функции. Това е тръба, която тече отляво надясно и извиква всяка функция с изхода на последната.

Да напишем функция, която връща нечие име.

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

Да напишем функция, която да стрингира низовете.

главен регистър = (низ) => string.toUpperCase ()
главна ( "Buckethead)
// „BUCKETHEAD“

Така че, ако искахме да получим и изписваме името на човек, бихме могли да направим това:

name = getName ({name: 'Buckethead'})
главни букви (име)
// „BUCKETHEAD“

Това е добре, но нека премахнем това междинно име на променлива

главни букви (getName ({name: 'Buckethead'}))

По-добре, но не обичам това гнездене. Може да стане твърде претъпкано. Какво става, ако искаме да добавим функция, която получава първите 6 знака от низ?

get6Characters = (string) => string.substring (0, 6)
get6Characters ( "Buckethead)
// „Кофа“

В резултат на което:

get6Characters (главни букви (getName ({name: 'Buckethead'})))
"КОФА"

Да станем наистина луди и да добавим функция към обратните низове.

обратен = (низ) => низ
  .split ( '')
  .обратен()
  .присъединяване('')
обратната ( "Buckethead)
// 'daehtekcuB'

Сега имаме:

обратен (get6Characters (главни букви (getName ({name: 'Buckethead'}))))
// „TEKCUB“

Може да получи малко ... много.

Тръп на помощ!

Вместо заглушаване на функции в рамките на функции или създаване на куп междинни променливи, нека да свършим всичко!

тръба(
  getName,
  Главна буква,
  get6Characters,
  обратен
) ({име: 'Buckethead'})
// „TEKCUB“

Чисто изкуство. Това е като списък с тодо!

Нека да преминем през него

За демонстрационни цели ще използвам изпълнение на тръба от една от функционалните статии за програмиране на Ерик Елиът.

тръба = (... fns) => x => fns.reduce ((v, f) => f (v), x)

Обичам това малко еднолинейно.

Използвайки параметрите за почивка, вижте моята статия за това, можем да изпълним n функции. Всяка функция приема резултата от предходната и всичко е намалено до една стойност.

И можете да го използвате точно както ние по-горе.

тръба(
  getName,
  Главна буква,
  get6Characters,
  обратен
) ({име: 'Buckethead'})
// „TEKCUB“

Ще разширя тръбата и ще добавя някои отчети за отстраняване на грешки и ще вървим ред по ред.

тръба = (... функции) => (стойност) => {
  дебъгер;
  функции за връщане
    .reduce ((currentValue, currentFunction) => {
       дебъгер;
       връщащ токFunction (currentValue);
    }, стойност)
}

Извикайте тръбата с нашия пример и оставете чудесата да се разгръщат.

Вижте локалните променливи. функции е масив от 4-те функции, а стойността е {name: 'Buckethead'}.

Тъй като използвахме параметри за почивка (отново вижте статията ми ), тръбата позволява да се използва произволен брой функции. Просто ще циклите и ще извикате всеки.

На следващия грешка ние сме вътре. Това е мястото, където currentValue се предава на currentFunction и се връща.

Виждаме, че резултатът е „Buckethead“, защото currentFunction връща свойството .name на всеки обект. Това ще бъде върнато в намаление, което означава, че следващият път става новата currentValue. Нека ударим следващия грешка и да видим

Сега currentValue е „Buckethead“, защото това се връща миналия път. currentFunction е главен, така че „BUCKETHEAD“ ще бъде следващата currentValue.

Същата идея, извадете първите 6 знака на „BUCKETHEAD“ и ги предайте на следващата функция.

обратен (". aedi emaS")

И сте готови!

Какво ще кажете за compose ()?

Просто е тръба в другата посока.

Така че, ако искате същия резултат като нашата тръба по-горе, ще направите обратното.

композиране (
  обратен,
  get6Characters,
  Главна буква,
  getName,
) ({име: 'Buckethead'})

Забележете как getName е последен във веригата и обратното е първо?

Ето бърза реализация на композиране, отново с любезното съдействие на Magical Eric Elliott от същата статия.

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

Ще оставя разширяването на тази функция с помощта на грешки като упражнение за вас. Играйте с него, използвайте го, оценете го. И най-важното - забавлявайте се!

До следващия път!

Пази се,
Язид Бзадоф