Tl;dr
{-# LANGUAGE InstanceSigs #-}
newtype Id t = Id t
instance Monad Id where
return :: t -> Id t
return = Id
(=<<) :: (a -> Id b) -> Id a -> Id b
f =<< (Id x) = f x
Prolog
Der Betreiber der Anwendung $
von Funktionen
forall a b. a -> b
ist kanonisch definiert
($) :: (a -> b) -> a -> b
f $ x = f x
infixr 0 $
im Sinne der Anwendung der Haskell-Primitivfunktion f x
( infixl 10
).
Zusammensetzung .
ist definiert als $
als
(.) :: (b -> c) -> (a -> b) -> (a -> c)
f . g = \ x -> f $ g x
infixr 9 .
und erfüllt die Äquivalenzen forall f g h.
f . id = f :: c -> d Right identity
id . g = g :: b -> c Left identity
(f . g) . h = f . (g . h) :: a -> d Associativity
.
ist assoziativ, und id
ist seine rechte und linke Identität.
Das Kleisli-Triple
In der Programmierung ist eine Monade ein Funktortypkonstruktor mit einer Instanz der Monadentypklasse. Es gibt mehrere äquivalente Definitions- und Implementierungsvarianten, die jeweils leicht unterschiedliche Intuitionen über die Monadenabstraktion vermitteln.
Ein Funktor ist ein Typkonstruktor f
von Art * -> *
mit einer Instanz der Funktypklasse.
{-# LANGUAGE KindSignatures #-}
class Functor (f :: * -> *) where
map :: (a -> b) -> (f a -> f b)
Zusätzlich zu den statisch erzwungenen Typprotokollen müssen Instanzen der Funktortypklasse den algebraischen Funktorengesetze forall f g.
map id = id :: f t -> f t Identity
map f . map g = map (f . g) :: f a -> f c Composition / short cut fusion
Faktor Berechnungen haben den Typ
forall f t. Functor f => f t
Eine Berechnung c r
besteht in Ergebnisse r
innerhalb Kontext c
.
Unäre monadische Funktionen oder Kleisli-Pfeile haben den Typ
forall m a b. Functor m => a -> m b
Kleisi-Pfeile sind Funktionen, die ein Argument benötigen a
und eine monadische Berechnung zurückgeben m b
.
Monaden sind kanonisch definiert in Form der Kleisli dreifach forall m. Functor m =>
(m, return, (=<<))
implementiert als die Typklasse
class Functor m => Monad m where
return :: t -> m t
(=<<) :: (a -> m b) -> m a -> m b
infixr 1 =<<
El Kleisli Identität return
ist ein Kleisli-Pfeil, der einen Wert fördert t
in monadischen Kontext m
. Erweiterung o Kleisli-Anwendung =<<
wendet einen Kleisli-Pfeil an a -> m b
zu Ergebnissen einer Berechnung m a
.
Kleisli Zusammensetzung <=<
ist in Bezug auf die Erweiterung definiert als
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> (a -> m c)
f <=< g = \ x -> f =<< g x
infixr 1 <=<
<=<
setzt zwei Kleisli-Pfeile zusammen, wobei der linke Pfeil auf die Ergebnisse der Anwendung des rechten Pfeils angewendet wird.
Instanzen der Monadentypklasse müssen der Monadengesetze am elegantesten im Sinne der Kleisli-Komposition: forall f g h.
f <=< return = f :: c -> m d Right identity
return <=< g = g :: b -> m c Left identity
(f <=< g) <=< h = f <=< (g <=< h) :: a -> m d Associativity
<=<
ist assoziativ, und return
ist seine rechte und linke Identität.
Identität
Der Identitätstyp
type Id t = t
ist die Identitätsfunktion für Typen
Id :: * -> *
Interpretiert als ein Funktor,
return :: t -> Id t
= id :: t -> t
(=<<) :: (a -> Id b) -> Id a -> Id b
= ($) :: (a -> b) -> a -> b
(<=<) :: (b -> Id c) -> (a -> Id b) -> (a -> Id c)
= (.) :: (b -> c) -> (a -> b) -> (a -> c)
Im kanonischen Haskell ist die Identitätsmonade wie folgt definiert
newtype Id t = Id t
instance Functor Id where
map :: (a -> b) -> Id a -> Id b
map f (Id x) = Id (f x)
instance Monad Id where
return :: t -> Id t
return = Id
(=<<) :: (a -> Id b) -> Id a -> Id b
f =<< (Id x) = f x
Option
Ein Optionstyp
data Maybe t = Nothing | Just t
verschlüsselt die Berechnungen Maybe t
das nicht unbedingt zu einem Ergebnis führt t
Berechnungen, die "fehlschlagen" können. Die Optionsmonade ist definiert
instance Functor Maybe where
map :: (a -> b) -> (Maybe a -> Maybe b)
map f (Just x) = Just (f x)
map _ Nothing = Nothing
instance Monad Maybe where
return :: t -> Maybe t
return = Just
(=<<) :: (a -> Maybe b) -> Maybe a -> Maybe b
f =<< (Just x) = f x
_ =<< Nothing = Nothing
a -> Maybe b
wird nur dann auf ein Ergebnis angewendet, wenn Maybe a
führt zu einem Ergebnis.
newtype Nat = Nat Int
Die natürlichen Zahlen können als ganze Zahlen größer oder gleich Null kodiert werden.
toNat :: Int -> Maybe Nat
toNat i | i >= 0 = Just (Nat i)
| otherwise = Nothing
Die natürlichen Zahlen sind bei der Subtraktion nicht geschlossen.
(-?) :: Nat -> Nat -> Maybe Nat
(Nat n) -? (Nat m) = toNat (n - m)
infixl 6 -?
Die Optionsmonade deckt eine grundlegende Form der Ausnahmebehandlung ab.
(-? 20) <=< toNat :: Int -> Maybe Nat
Liste
Die Listenmonade, über den Listentyp
data [] t = [] | t : [t]
infixr 5 :
und seine additive monoide Operation "append"
(++) :: [t] -> [t] -> [t]
(x : xs) ++ ys = x : xs ++ ys
[] ++ ys = ys
infixr 5 ++
kodiert nichtlinear Berechnung [t]
was eine natürliche Menge ergibt 0, 1, ...
der Ergebnisse t
.
instance Functor [] where
map :: (a -> b) -> ([a] -> [b])
map f (x : xs) = f x : map f xs
map _ [] = []
instance Monad [] where
return :: t -> [t]
return = (: [])
(=<<) :: (a -> [b]) -> [a] -> [b]
f =<< (x : xs) = f x ++ (f =<< xs)
_ =<< [] = []
Erweiterung =<<
verkettet ++
alle Listen [b]
die sich aus Anwendungen ergeben f x
eines Kleisli-Pfeils a -> [b]
zu Elementen von [a]
in eine einzige Ergebnisliste [b]
.
Es seien die richtigen Teiler einer positiven ganzen Zahl n
sein
divisors :: Integral t => t -> [t]
divisors n = filter (`divides` n) [2 .. n - 1]
divides :: Integral t => t -> t -> Bool
(`divides` n) = (== 0) . (n `rem`)
dann
forall n. let { f = f <=< divisors } in f n = []
Bei der Definition der Monadentypklasse wird anstelle der Erweiterung =<<
verwendet der Haskell-Standard seine Umkehrung, das binden Betreiber >>=
.
class Applicative m => Monad m where
(>>=) :: forall a b. m a -> (a -> m b) -> m b
(>>) :: forall a b. m a -> m b -> m b
m >> k = m >>= \ _ -> k
{-# INLINE (>>) #-}
return :: a -> m a
return = pure
Der Einfachheit halber wird in dieser Erklärung die Hierarchie der Typklassen verwendet
class Functor f
class Functor m => Monad m
In Haskell ist die aktuelle Standardhierarchie
class Functor f
class Functor p => Applicative p
class Applicative m => Monad m
denn nicht nur jede Monade ist ein Funktor, sondern auch jeder Applikativ ist ein Funktor und jede Monade ist ein Applikativ.
Unter Verwendung der Listenmonade wird der imperative Pseudocode
for a in (1, ..., 10)
for b in (1, ..., 10)
p <- a * b
if even(p)
yield p
entspricht in etwa dem sperren ,
do a <- [1 .. 10]
b <- [1 .. 10]
let p = a * b
guard (even p)
return p
das Äquivalent Monadenverständnis ,
[ p | a <- [1 .. 10], b <- [1 .. 10], let p = a * b, even p ]
und der Ausdruck
[1 .. 10] >>= (\ a ->
[1 .. 10] >>= (\ b ->
let p = a * b in
guard (even p) >> -- [ () | even p ] >>
return p
)
)
Do-Notation und Monadenverständnisse sind syntaktischer Zucker für verschachtelte Bind-Ausdrücke. Der bind-Operator wird für die lokale Namensbindung von monadischen Ergebnissen verwendet.
let x = v in e = (\ x -> e) $ v = v & (\ x -> e)
do { r <- m; c } = (\ r -> c) =<< m = m >>= (\ r -> c)
wobei
(&) :: a -> (a -> b) -> b
(&) = flip ($)
infixl 0 &
Die Schutzfunktion ist definiert als
guard :: Additive m => Bool -> m ()
guard True = return ()
guard False = fail
wo die Einheitentyp oder "leeres Tupel"
data () = ()
Additive Monaden die Unterstützung Auswahl y Ausfall kann durch eine Typklasse abstrahiert werden
class Monad m => Additive m where
fail :: m t
(<|>) :: m t -> m t -> m t
infixl 3 <|>
instance Additive Maybe where
fail = Nothing
Nothing <|> m = m
m <|> _ = m
instance Additive [] where
fail = []
(<|>) = (++)
donde fail
y <|>
ein Monoid bilden forall k l m.
k <|> fail = k
fail <|> l = l
(k <|> l) <|> m = k <|> (l <|> m)
y fail
ist das absorbierende/annihilierende Nullelement der additiven Monaden
_ =<< fail = fail
Wenn in
guard (even p) >> return p
even p
wahr ist, erzeugt der Wächter [()]
und, nach der Definition von >>
die lokale konstante Funktion
\ _ -> return p
wird auf das Ergebnis angewendet ()
. Wenn false, dann produziert der Guard die Liste monad's fail
( []
), was zu keinem Ergebnis für einen anzuwendenden Kleisli-Pfeil führt >>
zu, so dass diese p
wird übersprungen.
Staat
Berüchtigterweise werden Monaden zur Kodierung zustandsabhängiger Berechnungen verwendet.
A Statusprozessor ist eine Funktion
forall st t. st -> (t, st)
die einen Zustand übergeht st
und führt zu einem Ergebnis t
. Die Staat st
kann alles sein. Nichts, Flagge, Anzahl, Array, Griff, Maschine, Welt.
Die Art der Statusprozessoren wird gewöhnlich als
type State st t = st -> (t, st)
Die Zustandsprozessormonade ist die geartete * -> *
Funktor State st
. Kleisli-Pfeile der Zustandsprozessormonade sind Funktionen
forall st a b. a -> (State st) b
Im kanonischen Haskell ist die träge Version der Zustandsprozessormonade wie folgt definiert
newtype State st t = State { stateProc :: st -> (t, st) }
instance Functor (State st) where
map :: (a -> b) -> ((State st) a -> (State st) b)
map f (State p) = State $ \ s0 -> let (x, s1) = p s0
in (f x, s1)
instance Monad (State st) where
return :: t -> (State st) t
return x = State $ \ s -> (x, s)
(=<<) :: (a -> (State st) b) -> (State st) a -> (State st) b
f =<< (State p) = State $ \ s0 -> let (x, s1) = p s0
in stateProc (f x) s1
Ein Zustandsprozessor wird gestartet, indem ein Anfangszustand vorgegeben wird:
run :: State st t -> st -> (t, st)
run = stateProc
eval :: State st t -> st -> t
eval = fst . run
exec :: State st t -> st -> st
exec = snd . run
Der Zugriff auf den Zustand wird durch Primitive ermöglicht get
y put
Methoden der Abstraktion über zustandsabhängig Monaden:
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
class Monad m => Stateful m st | m -> st where
get :: m st
put :: st -> m ()
m -> st
erklärt eine Funktionsabhängigkeit des Zustandstyps st
über die Monade m
dass ein State t
wird zum Beispiel der Zustandstyp t
Einzigartig.
instance Stateful (State st) st where
get :: State st st
get = State $ \ s -> (s, s)
put :: st -> State st ()
put s = State $ \ _ -> ((), s)
wobei der Einheitentyp analog zu void
in C.
modify :: Stateful m st => (st -> st) -> m ()
modify f = do
s <- get
put (f s)
gets :: Stateful m st => (st -> t) -> m t
gets f = do
s <- get
return (f s)
gets
wird häufig mit Datensatzfeldzugriffsgeräten verwendet.
Das Äquivalent der Zustandsmonade für die Variable Threading
let s0 = 34
s1 = (+ 1) s0
n = (* 12) s1
s2 = (+ 7) s1
in (show n, s2)
donde s0 :: Int
ist das ebenso transparente, aber unendlich viel elegantere und praktischere
(flip run) 34
(do
modify (+ 1)
n <- gets (* 12)
modify (+ 7)
return (show n)
)
modify (+ 1)
ist eine Berechnung des Typs State Int ()
mit Ausnahme seiner Wirkung gleichbedeutend mit return ()
.
(flip run) 34
(modify (+ 1) >>
gets (* 12) >>= (\ n ->
modify (+ 7) >>
return (show n)
)
)
Das Monadengesetz der Assoziativität kann wie folgt formuliert werden >>=
forall m f g.
(m >>= f) >>= g = m >>= (\ x -> f x >>= g)
oder
do { do { do {
r1 <- do { x <- m; r0 <- m;
r0 <- m; = do { = r1 <- f r0;
f r0 r1 <- f x; g r1
}; g r1 }
g r1 }
} }
Wie in der ausdrucksorientierten Programmierung (z.B. Rust) stellt die letzte Anweisung eines Blocks dessen Ergebnis dar. Der Bind-Operator wird manchmal als "programmierbares Semikolon" bezeichnet.
Iterationskontrollstruktur-Primitive aus der strukturierten imperativen Programmierung werden monadisch emuliert
for :: Monad m => (a -> m b) -> [a] -> m ()
for f = foldr ((>>) . f) (return ())
while :: Monad m => m Bool -> m t -> m ()
while c m = do
b <- c
if b then m >> while c m
else return ()
forever :: Monad m => m t
forever m = m >> forever m
Eingabe/Ausgabe
data World
Die E/A-Weltzustandsprozessormonade ist eine Versöhnung von reinem Haskell und der realen Welt, von funktionaler denotativer und imperativer operativer Semantik. Ein nahes Analogon der tatsächlichen strikten Implementierung:
type IO t = World -> (t, World)
Interaktion wird durch unreine Primitive erleichtert
getChar :: IO Char
putChar :: Char -> IO ()
readFile :: FilePath -> IO String
writeFile :: FilePath -> String -> IO ()
hSetBuffering :: Handle -> BufferMode -> IO ()
hTell :: Handle -> IO Integer
. . . . . .
Die Unreinheit von Code, der IO
Primitive ist durch das Typsystem permanent protokolliert. Weil Reinheit großartig ist, passiert das, was in IO
, bleibt in IO
.
unsafePerformIO :: IO t -> t
Oder sollte es zumindest.
Die Typsignatur eines Haskell-Programms
main :: IO ()
main = putStrLn "Hello, World!"
erweitert sich auf
World -> ((), World)
Eine Funktion, die eine Welt transformiert.
Epilog
Die Kategorie, deren Objekte Haskell-Typen sind und deren Morphismen Funktionen zwischen Haskell-Typen sind, ist, "kurz und knapp", die Kategorie Hask
.
Ein Funktor T
ist eine Abbildung aus einer Kategorie C
zu einer Kategorie D
für jedes Objekt in C
ein Objekt in D
Tobj : Obj(C) -> Obj(D)
f :: * -> *
und für jeden Morphismus in C
ein Morphismus in D
Tmor : HomC(X, Y) -> HomD(Tobj(X), Tobj(Y))
map :: (a -> b) -> (f a -> f b)
donde X
, Y
sind Objekte in C
. HomC(X, Y)
es el Homomorphismenklasse aller Morphismen X -> Y
in C
. Der Funktor muss Morphismusidentität und Komposition bewahren, die "Struktur" von C
, in D
.
Tmor Tobj
T(id) = id : T(X) -> T(X) Identity
T(f) . T(g) = T(f . g) : T(X) -> T(Z) Composition
El Kategorie Kleisli einer Kategorie C
ist gegeben durch ein Kleisli-Tripel
<T, eta, _*>
eines Endofunktors
T : C -> C
( f
), ein Identitätsmorphismus eta
( return
), und ein Erweiterungsoperator *
( =<<
).
Jeder Kleisli-Morphismus in Hask
f : X -> T(Y)
f :: a -> m b
durch den Nebenstellenbetreiber
(_)* : Hom(X, T(Y)) -> Hom(T(X), T(Y))
(=<<) :: (a -> m b) -> (m a -> m b)
ist ein Morphismus in Hask
Die Kategorie Kleisli
f* : T(X) -> T(Y)
(f =<<) :: m a -> m b
Zusammensetzung in der Kategorie Kleisli .T
ist gegeben in Form der Erweiterung
f .T g = f* . g : X -> T(Z)
f <=< g = (f =<<) . g :: a -> m c
und erfüllt die Kategorie-Axiome
eta .T g = g : Y -> T(Z) Left identity
return <=< g = g :: b -> m c
f .T eta = f : Z -> T(U) Right identity
f <=< return = f :: c -> m d
(f .T g) .T h = f .T (g .T h) : X -> T(U) Associativity
(f <=< g) <=< h = f <=< (g <=< h) :: a -> m d
die unter Anwendung der Äquivalenztransformationen
eta .T g = g
eta* . g = g By definition of .T
eta* . g = id . g forall f. id . f = f
eta* = id forall f g h. f . h = g . h ==> f = g
(f .T g) .T h = f .T (g .T h)
(f* . g)* . h = f* . (g* . h) By definition of .T
(f* . g)* . h = f* . g* . h . is associative
(f* . g)* = f* . g* forall f g h. f . h = g . h ==> f = g
in Bezug auf die Erweiterung sind kanonisch gegeben
eta* = id : T(X) -> T(X) Left identity
(return =<<) = id :: m t -> m t
f* . eta = f : Z -> T(U) Right identity
(f =<<) . return = f :: c -> m d
(f* . g)* = f* . g* : T(X) -> T(Z) Associativity
(((f =<<) . g) =<<) = (f =<<) . (g =<<) :: m a -> m c
Monaden können auch nicht durch die Kleislsche Erweiterung, sondern durch eine natürliche Transformation definiert werden mu
in der Programmierung genannt join
. Eine Monade ist definiert durch die Begriffe mu
als ein Tripel über einer Kategorie C
eines Endofunktors
T : C -> C
f :: * -> *
und zwei natürliche Umformungen
eta : Id -> T
return :: t -> f t
mu : T . T -> T
join :: f (f t) -> f t
die die Äquivalenzen erfüllen
mu . T(mu) = mu . mu : T . T . T -> T . T Associativity
join . map join = join . join :: f (f (f t)) -> f t
mu . T(eta) = mu . eta = id : T -> T Identity
join . map return = join . return = id :: f t -> f t
Die Monadentypklasse wird dann definiert
class Functor m => Monad m where
return :: t -> m t
join :: m (m t) -> m t
Die kanonische mu
Implementierung der Optionsmonade:
instance Monad Maybe where
return = Just
join (Just m) = m
join Nothing = Nothing
El concat
Funktion
concat :: [[a]] -> [a]
concat (x : xs) = x ++ concat xs
concat [] = []
ist die join
der Listenmonade.
instance Monad [] where
return :: t -> [t]
return = (: [])
(=<<) :: (a -> [b]) -> ([a] -> [b])
(f =<<) = concat . map f
Implementierungen von join
kann aus der Erweiterungsform mit Hilfe der Äquivalenz übersetzt werden
mu = id* : T . T -> T
join = (id =<<) :: m (m t) -> m t
Die umgekehrte Übersetzung von mu
in die Erweiterungsform ist gegeben durch
f* = mu . T(f) : T(X) -> T(Y)
(f =<<) = join . map f :: m a -> m b
Aber warum sollte eine so abstrakte Theorie für die Programmierung von Nutzen sein?
Die Antwort ist einfach: Als Informatiker müssen wir Wertabstraktion ! Wenn wir die Schnittstelle zu einer Softwarekomponente entwerfen, müssen wir wollen es soll so wenig wie möglich über die Umsetzung verraten werden. Wir wollen in der Lage sein, die Implementierung durch viele Alternativen, viele andere "Instanzen" desselben "Konzepts" zu ersetzen. Wenn wir eine generische Schnittstelle zu vielen Programmbibliotheken entwerfen, ist es sogar noch wichtiger, dass die von uns gewählte Schnittstelle eine Vielzahl von Implementierungen hat. Es ist die Allgemeingültigkeit des Monadenkonzepts, die wir so sehr schätzen, es ist denn Die Kategorientheorie ist so abstrakt, dass ihre Konzepte für die Programmierung sehr nützlich sind.
Es ist daher kaum überraschend, dass die Verallgemeinerung der Monaden, die wir im Folgenden vorstellen, auch eine enge Verbindung zur Kategorientheorie hat. Wir betonen jedoch, dass unser Ziel sehr praktisch ist: Es geht nicht darum, die Kategorientheorie zu "implementieren", sondern einen allgemeineren Weg zur Strukturierung von Kombinator-Bibliotheken zu finden. Es ist einfach unser Glück, dass Mathematiker bereits einen Großteil der Arbeit für uns erledigt haben!
von Verallgemeinerung von Monaden auf Pfeile von John Hughes
13 Stimmen
Eric Lippert schrieb eine Antwort auf diese Fragen ( stackoverflow.com/questions/2704652/ ), die aufgrund einiger Probleme auf einer separaten Seite zu finden ist.
74 Stimmen
Hier ist eine neue Einführung in die Verwendung von Javascript - ich fand sie sehr lesenswert.
7 Stimmen
Siehe auch Verschiedene Arten, eine Monade zu sehen .
27 Stimmen
Siehe auch Monaden in Bildern
3 Stimmen
Eine Monade ist eine Reihe von Funktionen mit Hilfsoperationen. Siehe diese Antwort
0 Stimmen
Ein weiterer schneller Artikel, der der Antwort von sigfpe ähnelt: github.com/quchen/articles/blob/master/
0 Stimmen
Siehe meinen Artikel über FPComplete, in dem ich erkläre, WARUM man Monaden verwenden sollte (nicht wie sie funktionieren): bit.ly/MH9zRD
2 Stimmen
Die beste Erklärung, die ich bisher gehört habe, stammt von wikipedia: "Monaden sind programmierbare Semikolons."
0 Stimmen
Ich bin auf diesen Artikel gestoßen: stephanboyer.com/post/9/monads-part-1-a-design-pattern . Ich fand es ist die beste und effizienteste Konzeptvermittlung für Laien wie mich bisher. Der Autor hat eigentlich auch andere Artikel für Monaden.
0 Stimmen
Eine äußerst leicht verständliche Erklärung von Douglas Crockford: youtube.com/watch?v=dkZFtimgAcM
0 Stimmen
Monade ist kein Haskell-spezifisches Konzept, @HelderPereira. Ihr Retag scheint mir falsch zu sein.
1 Stimmen
@Palec Ich weiß, aber in der Frage wird Haskell erwähnt, und die am häufigsten gewählte Antwort verwendet Haskell, um sie zu erklären. Ich dachte nur, es wäre nützlich, um es für Leute, die Haskell lernen, einfacher zu machen, es zu finden, da dies ein sehr wichtiges Konzept der Sprache ist. Es steht Ihnen jedoch frei, es zu entfernen, wenn Sie denken, dass es keinen Sinn macht.
0 Stimmen
Ich möchte sagen, dass Monade ist eine Konstruktion, die Sie alle Ihre Mist in (tun tatsächlichen Job, aka Nebenwirkungen), und präsentieren Sie eine schicke Box, um Ihren Code functionnal (lesen Sie Nebeneffekt frei).
0 Stimmen
Monad ist EDSL. Siehe este : "Irgendwann bemerkte jemand: "Oh, um unreine Effekte aus reinem Code zu erhalten, muss ich Metaprogrammierung betreiben, was bedeutet, dass einer meiner Typen 'Programme, die ein X berechnen' sein muss. Ich möchte ein 'Programm, das ein X berechnet' und eine Funktion, die ein X nimmt und das nächste Programm erzeugt, ein 'Programm, das ein Y berechnet', nehmen und sie irgendwie zu einem 'Programm, das ein Y berechnet' zusammenfügen" (das ist die Bindungsoperation). Die IO-Monade war geboren."
0 Stimmen
Dieser Artikel von Tomasz Nurkiewicz ist die beste Erklärung, die ich für Java-Entwickler gefunden habe.
0 Stimmen
Kürzer: Monade ist (eingebettetes) Interpreter-Muster (wobei Anweisungen der zu interpretierenden Sprache erstklassige Werte unserer Programmiersprache selbst sind).
0 Stimmen
Monaden sind eingebettete domänenspezifische Sprachen, die Anweisungen (Semikolons) enthalten. Die Semikolons können Anweisungen in traditionellen prozeduralen Sprachen, Joins in SQL oder was immer Sie wollen darstellen. Da man Monaden zusammenführen kann, um Sprachen mit einer reicheren Semantik zu bilden, oder Monaden aufteilen kann, kann man Monaden auch als die SEMANTIK der Sprachen selbst betrachten.
2 Stimmen
Leider ist eine Monade eine Sache, die nur von Leuten erklärt werden kann, die nicht wissen, wie man etwas erklärt.