Die Funktion liftM
dreht eine Funktion, die eine Eingabe nimmt und eine Ausgabe erzeugt, die eine Eingabe in einer Monade nimmt und Ausgabe in derselben Monade erzeugt. Schauen wir uns seine Definition an:
Strings in Haskell sind Listen von Zeichen ( type String = [Char]
), also
Von Ihrem Anwendungscompiler leitet a = Char
, b = [Char]
, m a = [Char]
, m = []
ein. Also m b = [[Char]] = [String]
. Liste ist eine Monade mit return x = [x]
und (>>=) = concatMap
. Wenn wir uns also über die Definition spezialisieren, erhalten wir:
Und wenn wir die Argumente anwenden, erhalten wir:
%Vor% Der robotische Affenkopfoperator (:[])
ist nur der Abschnitt der Liste cons (:)
und die leere Liste []
, dh (:[])
entspricht (\x -> x:[])
; was wiederum mit der Listen-Syntax als (\x -> [x])
geschrieben werden kann.
Umgeschrieben auf diese Weise haben wir
%Vor% Das String-Literal "abc"
ist auch nur Syntaxzucker für die Zeichenliste ['a', 'b', 'c']
, also können wir das obige wiederum als
liftM
ist nur fmap
von den Dark Days, wenn Functor
war keine Oberklasse von Monad
und gab
Die Functor
Instanz von []
setzt fmap = map
und gibt
reduziert sich auf
%Vor%Oder zurück zur Zeichenfolgennotation
%Vor%Q.d.d.
liftM
entspricht fmap
, nur auf Monaden spezialisiert. (:[])
verwendet (:)
, um eine Funktion zu erstellen, die Listen eines Elements erzeugt. Genau wie (+2)
ist eine kompakte Möglichkeit, (\x -> x + 2)
zu schreiben, (:[])
entspricht (\x -> x : [])
oder (\x -> [x])
.
Ihr Ausdruck könnte dann folgendermaßen geschrieben sein:
%Vor% Das Vorhandensein von liftM
spiegelt die Tatsache wider, dass jedes legitime Monad
durch das Ausführen von Functor
zu einem fmap f m = m >>= \x -> return (f x)
gemacht werden kann. Sie können liftM
by fmap
immer ersetzen, daher sind die einzigen Gründe dafür:
, um fmap
kostenlos zu definieren, wenn Sie bereits eine Monad
-Instanz haben (und nicht die DeriveFunctor
GHC-Erweiterung verwenden möchten) und
eine völlig optionale Stilwahl (wenn Sie offensichtlich monadischen Code schreiben und fühlen, dass liftM
besser aussieht als fmap
).
liftM
ist definiert als:
Wir verwenden liftM
mit einer Liste (von Zeichen), also müssen wir uns die Listeninstanz von Monad
ansehen, um zu sehen, wie >>=
und return
definiert sind:
Also
%Vor% Die concat
auf der Außenseite und die [ ]
auf der Innenseite heben sich gegenseitig auf, also
Mit anderen Worten, liftM
in der Liste monad ist einfach map
.
weil eine Zeichenfolge wirklich nur eine Liste von Zeichen ist.
Tags und Links haskell