Monad (programmering)

Monad  är en speciell datatyp i funktionella programmeringsspråk , för vilka det är möjligt att ställa in en imperativ sekvens för att utföra vissa operationer på lagrade värden [1] . Monads låter dig ställa in sekvensen av operationer, utföra operationer med biverkningar och andra åtgärder som är svåra eller omöjliga att implementera i det funktionella programmeringsparadigmet på andra sätt.

Monadbegreppet och termen kommer ursprungligen från kategoriteori , där den definieras som en funktor med ytterligare struktur. Forskning som började i slutet av 1980-talet och början av 1990-talet fastställde att monader kunde föra till synes olika datavetenskapliga problem till en enda funktionell modell. Kategoriteori ställer också flera formkrav.[ vad? ] , de så kallade monadiska lagarna , som måste följas av vilken monad som helst och kan användas för att verifiera den monadiska koden.

Beskrivning

Monader används oftast i funktionella programmeringsspråk . Med en lat utvärderingsmodell är minskningsordningen okänd. Till exempel kan beräkningen 1 + 3 + 6reduceras till 1 + 9eller 4 + 6. Monader tillåter beställning av minskningen. Därför finns det ett ironiskt påstående att monader är ett sätt att överbelasta semikolonoperatorn.

En monad är en behållare som lagrar ett värde av en godtycklig typ. Den måste ha en bindningsfunktion som tar två argument: monadens nuvarande värde och en funktion som tar ett värde av den typ som den aktuella monaden innehåller och returnerar den nya monaden. Resultatet av att anropa bindfunktionen blir en ny monad som erhålls genom att applicera det första argumentet på det andra. Så här kan en monad i Java imperativspråket och en av dess implementeringar, Maybe-behållaren, se ut:

importera java.util.function.Function ; gränssnitt Monad < T > { < U > Monad < U > bind ( Funktion < T , Monad < U >> f ); } klass Kanske implementerar < T > Monad < T > { privat final Tval ; _ public Kanske ( T val ) { detta . val = val ; } public T getVal () { return val ; } @Override public < U > Monad < U > bind ( Funktion < T , Monad < U >> f ) { if ( val == null ) returnera ny Kanske < U > ( null ); återvända f . tillämpa ( val ); } } public class MonadApp { public static void main ( String [] args ) { Kanske < Integer > x = new Maybe <> ( 5 ); Monad < Heltal > y = x . binda ( v -> ny Kanske <> ( v + 1 )) . binda ( v -> new Maybe <> ( v * 2 )); System . ut . println ( (( Kanske < Heltal > ) y ). getVal () ); } }

Funktionella gränssnitt introducerade i Java 8 låter dig implementera ett monadliknande gränssnitt.

I Haskell

Monad-klassen finns i standardmodulen Prelude. Implementeringen av denna klass kräver vilken typ av enparameter som helst (genustyp * -> *). Monaden har fyra metoder

klass Funktion f där fmap :: ( a -> b ) -> f a -> f b klass Funktion f => Applikativ f där ren :: a -> f a ( <*> ) :: f ( a -> b ) -> f a -> f b ( *> ) :: f a -> f b -> f b ( <* ) :: f a -> f b -> f a -- m :: * -> * klass Applikativ m => Monad m där ( >>= ) :: m a -> ( a -> m b ) -> m b ( >> ) :: m a -> m b -> m b -- implementerat som standard: a >> b = a >>= \_ -> b return :: a -> m a -- = rent misslyckande :: String -> m a -- by- calls errorWithoutStackTrace som standard

Metoden returnkan vara förvirrande för programmerare som är bekanta med imperativa språk: den avbryter inte beräkningen, utan packar bara in ett godtyckligt värde av typen ai en monad m. Metoden failhar inget att göra med monadernas teoretiska natur, utan används vid ett mönstermatchningsfel inom en monadisk utvärdering. [2] ). Operatören >>=är en bindande funktion. Operatören >> är ett specialfall av operatören >>=, som används när resultatet av bindningen inte är viktigt för oss.

Några typer som implementerar Monad-klassen:

  • IO, används för funktioner med biverkningar. IO-konstruktörer är dolda från programmeraren, och det finns inga monaduppackningsfunktioner. Detta förhindrar att smutsiga funktioner anropas från rena.
  • Maybe. Utvärderingen avbryts om inget värde tas emot.
  • [] (список). Beräkningen avbryts när listan är tom. För en icke-tom lista anropar operatören >>=en funktion för varje element i listan.
  • Reader.
  • Writer.
  • State. Utöver möjligheterna låter Reader dig ändra tillstånd.

Språket har också do-notation, vilket är ett bekvämare sätt att skriva monadiska funktioner. I det här exemplet f1använder den do-notation, men f2skrivs med bindoperatorer:

f1 = gör s <- getLine putStrLn $ "Hej " ++ s putStrLn "Adjö" f2 = getLine >>= ( \ s -> putStrLn $ "Hej " ++ s ) >> putStrLn "Adjö"

Anteckningar

  1. Dushkin-FP, 2008 , sid. 215.
  2. Evgeny Kirpichev. Monader i Haskell . Monader är "en generalisering av några välbekanta idiom, och även som en annan metod för att abstrahera dem."

Länkar

Handledningar

Andra artiklar

Litteratur

  • Dushkin R.V. Säkerhet // Programmeringstrick // Funktioner // Språksyntax och idiom // Haskell Language Reference / Kap. ed. D.A. Movchan. - M. : DMK Press , 2008. - S. 37-38. — 554 sid. - 1500 exemplar.  - ISBN 5-94074-410-9 , BBC 32.973.26-018.2, UDC 004.4.
  • Dushkin R. V. Funktionell programmering i Haskell. — M. : DMK Press, 2008. — 609 sid. — ISBN 5-94074-335-8 .
  • Peyton-Jones, Simon . 8. Föreläsning: Standard Beginning (Prelude) // Haskell Language and Libraries 98 .
  • Erkok Levent. Värderekursion i monadiska beräkningar. Oregon Graduate Institute. - 2002. - 162 sid.