Vll tritt da eine Schwäche von mir bei den formalen Grundlagen zutage, aber sowohl Currying als auch Monads sind so Begriffe, die ich (z.B. bei Hackernews) öfter mal lese, die mir aber schlicht nichts sagen. Kann mich nicht erinnern, darüber je was gelernt zu haben. Dabei hatte ich ja funktionale Programmierung, mochte sie schlußendlich sogar, und da wird wohl beides genutzt.
Nach meiner Faustregel hat es niemand verstanden, den ich bis jetzt gelesen habe, denn ich finde keine einfache Erklärung. Vielleicht kann hier jemand helfen? Ich beschreibe mal, was ich bisher habe.
Currying
Abgeleitet aus der comp.lang.functional-FAQ: Das scheint total unspannend zu sein. Hat man nur einen Parameter zur Verfügung, dann kann man um
f(x,y)
auszudrücken, x durch eine Funktion ersetzen, also:
(f'(x))(y) = f (x,y)
Das solls sein?
Gut, mir ist klar, dass man das gebrauchen kann, wenn man in einer seltsamen Sprache zwar lambda zur Verfügung hat, aber nur einparametrige Funktionen. Das wäre dann ein theoretisches Konstrukt ohne Praxisrelevanz, das höchstens dann gut ist, wenn eine solche Sprache zu leichteren Beweisen führt und man sie nutzt, weil man bewiesen richtigen Programmcode braucht.
Monads
Hier geht mein im Studium gestählter Bullshit-Sensor an. Und zwar, weil hier die FAQ jede Antwort darüber verweigert, was es ist, und nur darüber schreibt, wofür es gut ist:
What is a "monad", and what are they used for?
The concept of a monad comes from category theory; full details can be found in any standard textbook on the subject. Much of the interest ...
Was mich wieder zu meiner Frage führt, ob es wirklich Dinge gibt, die so kompliziert und trotzdem wichtig sind, dass man sie nicht mehr mit einfachen Worten ausdrücken kann (siehe die Sprachbarriere bei FGdI).
Wie auch immer, aus diesem Paper und Wikipedia wird die Essenz des Begriffs nicht wirklich klar. Laut dem Paper: Ein Monad ist ein Ding M, das Seiteneffekte darstellt, und das man deswegen vor den normalen Typ stellt? Das Divisionsbeispiel aus der Wikipedia ist für mich an sich einleuchtend (abgesehen von der grauenhaften Syntax):
(//) :: Maybe a -> Maybe a -> Maybe a
_ // Nothing = Nothing
Nothing // _ = Nothing
_ // Just 0 = Nothing
Just x // Just y = Just (x / y)
Statt eine Division / zu definieren, die Zahlen zurückgibt (und dann Sonderfälle wie die Division durch 0 fangen zu dürfen), definiere ich eine Division //, die entweder Zahlen oder einen Ausweichtyp ausgibt. Ähnlich wie Listen, die entweder Elemente oder ein Schlußsymbol beinhalten. Und wieder: Ist das alles?
Ich muss es bezweifeln, sonst könnte man es einfach erklären.