(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-5LHNRP9'); thecodest, Autor na The Codest - Strana 8 z 13

Úvod

Často je obtížné udržovat nemodifikovatelnost. Vzor zabalení data do kontejneru přichází na pomoc. Zajišťuje hodnoty tak, aby manipulace s nimi byla bezpečná s vyloučením vedlejších účinků.

Pokud jste tu noví, určitě si přečtěte mé poslední dva díly týkající se funkcionálního programování na stránkách The Codest blog o:

Funktor

Nemá žádnou složitou logiku. Jeho hlavním úkolem je obalit kontext a provádět na něm funkce, které obdrží zvenčí. Při každé změně hodnoty je přebalena a vrácena nová instance kontejneru. Při volání mapa která provádí určitou akci, vrací novou instanci kontejneru s hodnotou vrácenou předanou funkcí, přičemž je zachován princip nemodifikovatelnosti.

Prohlášení

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

mapa - užitečné, když chcete změnit stav hodnoty v kontejneru, ale ještě ji nechcete vrátit.

řetěz - se používá, pokud chcete funkci předat hodnotu, aniž byste změnili stav kontejneru. Obvykle na konci mapa telefonáty.

z - vrátit aktuální hodnotu

Imperativní příklad

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

const randomNumber = randomInt(200) // vrací číslo mezi 0 a 200

decrease(randomNumber) // vrací (číslo mezi 0 a 200) - 1

Deklarativní příklad

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() // vrací číslo mezi 0 a 200
randomNumber.chain(decrease) // vrací (číslo mezi 0 a 200) - 1

Monády

Někdy je kromě funkcí, které spouštějí nový stav hodnoty, potřeba další logika skrytá v kontejneru. V tomto případě se hodí monáda, která je rozšířením funkce funktor. Může například rozhodnout, co se má stát, když hodnota nabývá určité hodnoty, nebo jakou cestou se mají ubírat další akce.

Monáda Možná

Monády možná řeší problém hodnot, které nevracejí true. Když se to stane, následné mapa je ignorováno, ale umožňuje vrátit alternativu voláním příkazu getOr metoda. Umožňuje vyhnout se použití operátorů if / else, které jsou oblíbené v metodách typu imperativ programování. Tato monáda se skládá ze tří kontejnerů:

Nic - se spustí, když do kontejneru spadne hodnota, která není true nebo filtr metoda vrací false. Používá se k simulaci provádění funkce. To znamená, že tento kontejner přijme funkci, ale neprovede ji.

Jen - je to hlavní kontejner, který vykonává všechny funkce, ale pokud se hodnota změní na hodnotu false nebo filtr se vrátí false, předá ji metodě Nic kontejner.

Možná - Vezmu počáteční hodnotu a rozhodnu se, jaký kontejner zavolat na začátku.

Prohlášení

const Just = value => ({
map: fn => Maybe(fn(value)),
chain: fn => fn(value),
of: () => value,
getOr: () => value,
filter: fn => fn(value) ? Just(value) : Nic(),
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'
? nic()
: Just(value)
metody tabulky funktor

Nyní navážeme na předchozí příklad o podmínce. Pokud je max větší než nula, funkce se provede. V opačném případě vrátí 0.

Imperativní příklad

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

const bookMiddlePage = 200

const randomPage = randomInt(10) || bookMiddlePage // vrací náhodnou hodnotu
const randomPage = randomInt(-10) || bookMiddlePage // vrací 200

Deklarativní příklad

const randomIntWrapper = (max) =>
Maybe(max)
.filter(max => max > 0) // hodnota false ignoruje další volání
.map(increase)
.map(multiplyBy(Math.random()))
.map(Math.floor)

const bookMiddlePage = 200

// Jen kontejner
const randomPage = randomIntWrapper(10).getOr(bookMiddlePage) // vrací náhodný údaj
// Nic kontejneru
const randomPage = randomIntWrapper(-10).getOr(bookMiddlePage) // vrací 200


banner spolupráce

cs_CZCzech