Monad (programování)

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.

Popis

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.

V Haskellu

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:

  • IO, používá se pro funkce s vedlejšími účinky. Konstruktory IO jsou před programátorem skryté a neexistují žádné funkce rozbalování monád. Tím se zabrání volání špinavých funkcí z čistých.
  • Maybe. Vyhodnocení se přeruší, pokud je přijata hodnota Nic.
  • [] (список). Výpočet se přeruší, když je seznam prázdný. U neprázdného seznamu operátor >>=zavolá funkci pro každý prvek seznamu.
  • Reader.
  • Writer.
  • State. Kromě možností vám Reader umožňuje změnit stav.

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"

Poznámky

  1. Dushkin-FP, 2008 , str. 215.
  2. Jevgenij Kirpichev. Monády v Haskellu . Monády jsou „zobecněním některých známých idiomů a také jako další metoda pro jejich abstrahování“.

Odkazy

Návody

Další články

Literatura

  • Dushkin R.V. Zabezpečení // Programátorské triky // Funkce // Syntaxe jazyka a idiomy // Haskell Language Reference / Kap. vyd. D. A. Movchan. - M. : DMK Press , 2008. - S. 37-38. — 554 s. - 1500 výtisků.  - ISBN 5-94074-410-9 , BBC 32.973.26-018.2, MDT 004.4.
  • Dushkin R. V. Funkční programování v Haskellu. — M. : DMK Press, 2008. — 609 s. — ISBN 5-94074-335-8 .
  • Peyton-Jones, Simon . 8. Přednáška: Standardní začátek (předehra) // Haskell Language and Libraries 98 .
  • Erkok Levent. Hodnotová rekurze v monadických výpočtech. Oregon Graduate Institute. - 2002. - 162 s.