window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster już istnieje') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() Programowanie funkcyjne w JavaScript Część 3 - Funktor i Monada Maybe - The Codest
The Codest
  • O nas
  • Nasze Usługi
    • Software Development
      • Frontend Development
      • Backend Development
    • Zespoły IT
      • Programiści frontendowi
      • Backend Dev
      • Inżynierowie danych
      • Inżynierowie rozwiązań chmurowych
      • Inżynierowie QA
      • Inne
    • Konsultacje IT
      • Audyt i doradztwo
  • Branże
    • Fintech i bankowość
    • E-commerce
    • Adtech
    • Healthtech
    • Produkcja
    • Logistyka
    • Motoryzacja
    • IOT
  • Wartość dla
    • CEO
    • CTO
    • Delivery Managera
  • Nasz zespół
  • Case Studies
  • Nasze Know How
    • Blog
    • Meetups
    • Webinary
    • Raporty
Kariera Skontaktuj się z nami
  • O nas
  • Nasze Usługi
    • Software Development
      • Frontend Development
      • Backend Development
    • Zespoły IT
      • Programiści frontendowi
      • Backend Dev
      • Inżynierowie danych
      • Inżynierowie rozwiązań chmurowych
      • Inżynierowie QA
      • Inne
    • Konsultacje IT
      • Audyt i doradztwo
  • Wartość dla
    • CEO
    • CTO
    • Delivery Managera
  • Nasz zespół
  • Case Studies
  • Nasze Know How
    • Blog
    • Meetups
    • Webinary
    • Raporty
Kariera Skontaktuj się z nami
Strzałka w tył WSTECZ
2022-06-21
Software Development

Programowanie funkcyjne w JavaScript Część 3 - Funktor i Monada Maybe

The Codest

Paweł Ged

Vue.js Developer

Sprawdź trzecią część naszej serii artykułów Power of functional programming w JavaScript. Tym razem nasz ekspert JavaScript wyjaśnia więcej na temat Functor i Monad Maybe.

Wprowadzenie

Często zachowanie niemodyfikowalności jest trudne do utrzymania. Z pomocą przychodzi wzorzec opakowywania danych w kontener. Zabezpiecza on wartości tak, że operowanie na nich jest bezpieczne z wykluczeniem efektów ubocznych.

Jeśli jesteś tu nowy, koniecznie sprawdź moje ostatnie 2 części dotyczące programowania funkcjonalnego na blogu The Codest:

  • Część 1 - Wprowadzenie
  • Część 2 - Kombinatory

Funktor

Nie ma złożonej logiki. Jego głównym zadaniem jest opakowywanie kontekstu i wykonywanie na nim funkcji, które otrzymuje z zewnątrz. Za każdym razem, gdy zmienia się wartość, nowa instancja kontenera jest przepakowywana i zwracana. Podczas wywoływania funkcji mapa która wykonuje określoną akcję, zwraca nową instancję kontenera z wartością zwróconą przez przekazaną funkcję, zachowując zasadę niemodyfikowalności.

Deklaracja

 const Functor = value => ({
     map: fn => Functor(fn(value)),
     chain: fn => fn(value),
     of: () => value
 });

mapa - przydatna, gdy chcesz zmienić stan wartości w kontenerze, ale nie chcesz jej jeszcze zwracać.

łańcuch - używany, jeśli chcesz przekazać wartość do funkcji bez modyfikowania stanu kontenera. Zwykle na końcu mapa połączenia.

z - zwraca bieżącą wartość

Przykład imperatywu

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

const randomNumber = randomInt(200) // zwraca liczbę pomiędzy 0 a 200

decrease(randomNumber) // zwraca (liczbę pomiędzy 0 a 200) - 1

Przykład deklaratywny

const randomIntWrapper = (max) =>
Functor(max)
.map(increase) // max + 1
.map(multiplyBy(Math.random())) // Math.random() * (max + 1)
.map(Math.floor) // Math.floor(Math.random() * (max + 1))

const randomNumber = randomIntWrapper(200)

randomNumber.of() // zwraca liczbę pomiędzy 0 a 200
randomNumber.chain(decrease) // zwraca (liczbę między 0 a 200) - 1

Monada

Czasami, oprócz funkcji wywołujących nowy stan wartości, potrzebna jest dodatkowa logika ukryta w kontenerze. Tutaj przydaje się monada, która jest rozszerzeniem funkcji funktor. Może na przykład zdecydować, co powinno się stać, gdy wartość ma określoną wartość lub jaką ścieżkę mają obrać kolejne działania.

Monada może

Monada być może rozwiązuje problem wartości, które nie zwracają prawdy. Kiedy tak się dzieje, kolejne mapa są ignorowane, ale umożliwia zwrócenie alternatywy poprzez wywołanie funkcji getOr method. Pozwala to uniknąć stosowania operatorów if / else, które są popularne w metodach imperatywny programowanie. Monada ta składa się z trzech kontenerów:

Nic - uruchamia się, gdy wartość, która nie jest prawdziwa, wpada do kontenera lub filtr zwraca wartość false. Służy do symulacji wykonania funkcji. Oznacza to, że ten kontener odbiera funkcję, ale jej nie wykonuje.

Po prostu - jest to główny kontener, który wykonuje wszystkie funkcje, ale jeśli wartość zmieni się na wartość false lub filtr zwróci wartość false, przekaże ją do metody Nic pojemnik.

Może - Biorę wartość początkową i decyduję, który kontener wywołać na początku.

Deklaracja

const Just = value => ({
map: fn => Maybe(fn(value)),
chain: fn => fn(value),
of: () => value,
getOr: () => value,
filter: fn => fn(value) ? Just(value) : Nothing(),
type: 'just'
});

const Nothing = () => ({
map: fn => Nothing(),
chain: fn => fn(),
of: () => Nothing(),
getOr: substitute => substitute,
filter: () => Nothing(),
type: 'nothing'
});

const Maybe = value =>
value == null || value == undefined || value.type == 'nothing'
? Nothing()
: Just(value)
tabela metody funktor

Rozbudujmy teraz poprzedni przykład o warunek. Jeśli wartość max jest większa od zera, funkcja zostanie wykonana. W przeciwnym razie funkcja zwróci 0.

Przykład imperatywu

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

const bookMiddlePage = 200

const randomPage = randomInt(10) || bookMiddlePage // zwraca losową wartość
const randomPage = randomInt(-10) || bookMiddlePage // zwraca 200

Przykład deklaratywny

const randomIntWrapper = (max) =>
Maybe(max)
.filter(max => max > 0) // wartość false ignoruje dalsze wywołania
.map(increase)
.map(multiplyBy(Math.random()))
.map(Math.floor)

const bookMiddlePage = 200

// Tylko kontener
const randomPage = randomIntWrapper(10).getOr(bookMiddlePage) // zwraca losową wartość
// Kontener bez niczego
const randomPage = randomIntWrapper(-10).getOr(bookMiddlePage) // zwraca 200


baner współpracy

Powiązane artykuły

Software Development

Asynchroniczny i jednowątkowy JavaScript?

JavaScript jest językiem jednowątkowym, a jednocześnie nieblokującym, asynchronicznym i współbieżnym. Ten artykuł wyjaśni ci, jak to się dzieje.

Łukasz Kolko
E-commerce

Dylematy cyberbezpieczeństwa: Wycieki danych

Przedświąteczna gorączka trwa w najlepsze. W poszukiwaniu prezentów dla najbliższych ludzie coraz chętniej "szturmują" sklepy internetowe

The Codest
Jakub Jakubowicz CTO & Współzałożyciel

Subskrybuj naszą bazę wiedzy i bądź na bieżąco!

    O nas

    The Codest - Międzynarodowa firma programistyczna z centrami technologicznymi w Polsce.

    Wielka Brytania - siedziba główna

    • Office 303B, 182-184 High Street North E6 2JA
      Londyn, Anglia

    Polska - lokalne centra technologiczne

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Warszawa, Polska

      The Codest

    • Strona główna
    • O nas
    • Nasze Usługi
    • Case Studies
    • Nasze Know How
    • Kariera
    • Słownik

      Nasze Usługi

    • Konsultacje IT
    • Software Development
    • Backend Development
    • Frontend Development
    • Zespoły IT
    • Backend Dev
    • Inżynierowie rozwiązań chmurowych
    • Inżynierowie danych
    • Inne
    • Inżynierowie QA

      Raporty

    • Fakty i mity na temat współpracy z zewnętrznym partnerem programistycznym
    • Z USA do Europy: Dlaczego amerykańskie startupy decydują się na relokację do Europy?
    • Porównanie centrów rozwoju Tech Offshore: Tech Offshore Europa (Polska), ASEAN (Filipiny), Eurazja (Turcja)
    • Jakie są największe wyzwania CTO i CIO?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Warunki korzystania z witryny

    Copyright © 2025 by The Codest. Wszelkie prawa zastrzeżone.

    pl_PLPolish
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench arArabic it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek pl_PLPolish