Ú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)

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
