Monad er en speciel datatype i funktionelle programmeringssprog , for hvilke det er muligt at indstille en imperativ sekvens for at udføre visse operationer på lagrede værdier [1] . Monader giver dig mulighed for at indstille rækkefølgen af operationer, udføre operationer med bivirkninger og andre handlinger, der er svære eller umulige at implementere i det funktionelle programmeringsparadigme på andre måder.
Monadebegrebet og begrebet kommer oprindeligt fra kategoriteori , hvor det er defineret som en funktor med yderligere struktur. Forskning, der begyndte i slutningen af 1980'erne og begyndelsen af 1990'erne, fastslog, at monader kunne bringe tilsyneladende forskellige computervidenskabelige problemer ind i en enkelt funktionel model. Kategoriteori stiller også flere formelle krav.[ hvad? ] , de såkaldte monadiske love , som skal overholdes af enhver monade og kan bruges til at verificere den monadiske kode.
Monader er mest almindeligt anvendt i funktionelle programmeringssprog . Med en doven evalueringsmodel er rækkefølgen af reduktion ukendt. For eksempel kan beregningen 1 + 3 + 6reduceres til 1 + 9eller 4 + 6. Monader tillader at bestille reduktionen. Derfor er der en ironisk påstand om, at monader er en måde at overbelaste semikolonoperatoren på.
En monade er en beholder, der gemmer en værdi af en vilkårlig type. Den skal have en bindefunktion, der tager to argumenter: den aktuelle værdi af monaden, og en funktion, der tager en værdi af den type, den nuværende monaden indeholder, og returnerer den nye monaden. Resultatet af at kalde bindefunktionen vil være en ny monade opnået ved at anvende det første argument på det andet. Sådan kunne en monade i Java imperativsproget og en af dens implementeringer, Maybe-beholderen, se ud:
import java.util.function.Function ; interface Monade < T > { < U > Monade < U > bind ( Funktion < T , Monade < U >> f ); } klasse Måske implementerer < T > Monad < T > { privat finale Tval ; _ offentlig Måske ( T val ) { dette . val = val ; } public T getVal () { return val ; } @Override public < U > Monade < U > bind ( Funktion < T , Monade < U >> f ) { if ( val == null ) returner ny Måske < U > ( null ); returnere f . anvende ( val ); } } public class MonadApp { public static void main ( String [] args ) { Måske < Integer > x = new Maybe <> ( 5 ); Monade < Heltal > y = x . binde ( v -> ny Måske <> ( v + 1 )) . binde ( v -> ny Måske <> ( v * 2 )); System . ud . println ( (( Måske < Heltal > ) y ). getVal () ); } }Funktionelle grænseflader introduceret i Java 8 giver dig mulighed for at implementere en monadelignende grænseflade.
Monad-klassen er til stede i standardmodulet Prelude. Implementeringen af denne klasse kræver enhver type med én parameter (slægtstype * -> *). Monaden har fire metoder
klasse Functor f hvor fmap :: ( a -> b ) -> f a -> f b klasse Funktion f => Applikativ f hvor ren :: a -> f a ( <*> ) :: f ( a -> b ) -> f a -> f b ( *> ) :: f a -> f b -> f b ( <* ) :: f a -> f b -> f a -- m :: * -> * klasse Applikativ m => Monade m hvor ( >>= ) :: m a -> ( a -> m b ) -> m b ( >> ) :: m a -> m b -> m b -- implementeret som standard: a >> b = a >>= \_ -> b return :: a -> m a -- = ren fejl :: Streng -> m a -- by-kald fejlUdenStackTrace som standardMetoden returnkan være forvirrende for programmører, der er fortrolige med imperative sprog: den afbryder ikke beregningen, men pakker kun en vilkårlig værdi af typen aind i en monade m. Metoden failhar intet at gøre med monaders teoretiske karakter, men bruges i tilfælde af en mønstertilpasningsfejl inden for en monadisk evaluering. [2] ). Operatøren >>=er en bindende funktion. Operatøren >> er et specialtilfælde af operatøren >>=, der bruges, når resultatet af bindingen ikke er vigtigt for os.
Nogle typer, der implementerer Monad-klassen:
Sproget har også do-notation, som er en mere bekvem måde at skrive monadiske funktioner på. I dette eksempel f1bruger den do-notation, men er f2skrevet ved hjælp af bind-operatorer:
f1 = do s <- getLine putStrLn $ "Hej " ++ s putStrLn "Farvel" f2 = getLine >>= ( \ s -> putStrLn $ "Hej " ++ s ) >> putStrLn "Farvel"