Monad je speciální datový typ ve funkcionálních programovacích jazycích , u kterého je možné nastavit imperativní sekvenci pro provádění určitých operací s uloženými hodnotami [1] . Monády umožňují nastavit posloupnost operací, provádět operace s vedlejšími efekty a další akce, které je obtížné nebo nemožné implementovat do paradigmatu funkčního programování jinými způsoby.
Pojem monáda a termín původně pochází z teorie kategorií , kde je definován jako funktor s doplňkovou strukturou. Výzkum začínající koncem 80. a začátkem 90. let 20. století prokázal, že monády mohou přinést zdánlivě nesourodé problémy informatiky do jediného funkčního modelu. Teorie kategorií také předkládá několik formálních požadavků.[ co? ] , tzv. monadické zákony , které musí dodržovat každá monáda a lze je použít k ověření monadického kódu.
Monády se nejčastěji používají ve funkcionálních programovacích jazycích . U modelu líného hodnocení je pořadí redukce neznámé. Výpočet 1 + 3 + 6lze například zredukovat na 1 + 9nebo 4 + 6. Monády umožňují objednání snížení. Existuje proto ironické tvrzení, že monády jsou způsob, jak přetížit operátor středník.
Monáda je kontejner, který ukládá hodnotu libovolného typu. Musí mít funkci vazby, která přebírá dva argumenty: aktuální hodnotu monády a funkci, která přebírá hodnotu typu, který aktuální monáda obsahuje, a vrací novou monádu. Výsledkem volání funkce bind bude nová monáda získaná aplikací prvního argumentu na druhý. Takto by mohla vypadat monáda v imperativním jazyce Java a jedna z jejích implementací, kontejner Maybe:
import java.util.function.Function ; rozhraní Monad < T > { < U > Monad < U > bind ( Funkce < T , Monad < U >> f ); } třída Možná < T > implementuje Monad < T > { soukromé finále Tval ; _ public Možná ( T val ) { this . val = val ; } public T getVal () { return val ; } @Override public < U > Monad < U > bind ( Function < T , Monad < U >> f ) { if ( val == null ) return new Maybe < U > ( null ); návrat f . aplikovat ( val ); } } public class MonadApp { public static void main ( String [] args ) { Možná < Celé číslo > x = new Možná <> ( 5 ); Monad < Integer > y = x . bind ( v -> new Možná <> ( v + 1 )) . bind ( v -> new Možná <> ( v * 2 )); Systém . ven . println ( (( Možná < Integer > ) y ). getVal () ); } }Funkční rozhraní představená v Javě 8 vám umožňují implementovat rozhraní podobné monád.
Třída Monad je přítomna ve standardním modulu Prelude. Implementace této třídy vyžaduje libovolný typ s jedním parametrem (genus type * -> *). Monáda má čtyři metody
třída Funktor f kde fmap :: ( a -> b ) -> f a -> f b funktor třídy f => Aplikativní f kde čisté :: a -> f a ( <*> ) :: f ( a -> b ) -> f a -> f b ( *> ) :: f a -> f b -> f b ( <* ) :: f a -> f b -> f a -- m :: * -> * třída Aplikativní m => Monad m kde ( >>= ) :: m a -> ( a -> m b ) -> m b ( >> ) :: m a -> m b -> m b -- implementováno ve výchozím nastavení: a >> b = a >>= \_ -> b return :: a -> m a -- = čisté selhání :: Řetězec -> m a -- voláním errorWithoutStackTrace ve výchozím nastaveníTato metoda returnmůže být matoucí pro programátory obeznámené s imperativními jazyky: nepřeruší výpočet, ale pouze zabalí libovolnou hodnotu typu ado monády m. Metoda failnemá nic společného s teoretickou povahou monád, ale používá se v případě chyby shody vzoru v monadickém hodnocení. [2] ). Operátor >>=je vazebná funkce. Operátor >> je speciální případ operátora >>=, který se používá, když pro nás není důležitý výsledek vazby.
Některé typy, které implementují třídu Monad:
Jazyk má také do-notaci, což je pohodlnější způsob zápisu monadických funkcí. V tomto příkladu f1používá do-notation, ale je f2napsán pomocí operátorů bind:
f1 = do s <- getLine putStrLn $ "Ahoj" ++ s putStrLn "Sbohem" f2 = getLine >>= ( \ s -> putStrLn $ "Dobrý den " ++ s ) >> putStrLn "Sbohem"