wie funktioniert liftM (: [])?

7

Ich versuche den folgenden Ausdruck zu verstehen. Es konvertiert die Liste der Zeichen ['a','b','c'] in eine Liste von Zeichenfolgen ["a", "b", "c"]

%Vor%

Wie passiert das?

    
akonsu 01.08.2015, 15:04
quelle

4 Antworten

10

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:

%Vor%

Strings in Haskell sind Listen von Zeichen ( type String = [Char] ), also

%Vor%

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:

%Vor%

Und wenn wir die Argumente anwenden, erhalten wir:

%Vor%     
aemxdp 01.08.2015, 15:44
quelle
12

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

umschreiben %Vor%

liftM ist nur fmap von den Dark Days, wenn Functor war keine Oberklasse von Monad und gab

%Vor%

Die Functor Instanz von [] setzt fmap = map und gibt

%Vor%

reduziert sich auf

%Vor%

Oder zurück zur Zeichenfolgennotation

%Vor%

Q.d.d.

    
Cactus 01.08.2015 16:01
quelle
9

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 ).

duplode 01.08.2015 15:44
quelle
7

liftM ist definiert als:

%Vor%

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:

%Vor%

Also

%Vor%

Die concat auf der Außenseite und die [ ] auf der Innenseite heben sich gegenseitig auf, also

%Vor%

Mit anderen Worten, liftM in der Liste monad ist einfach map .

%Vor%

weil eine Zeichenfolge wirklich nur eine Liste von Zeichen ist.

    
melpomene 01.08.2015 15:45
quelle

Tags und Links