Dies ist der Code, auf den ich irgendwo gestoßen bin, aber ich möchte wissen, wie das funktioniert:
findIndices :: (a -> Bool) -> [a] -> [Int]
findIndices _ [] = []
findIndices pred xs = map fst (filter (pred . snd) (zip [0..] xs))
Ausgabe: findIndices (== 0) [1,2,0,3,0] == [2,4] , wobei pred (== 0) & xs [1,2,0,3,0] ist
Ich werde etwas von meinem Verständnis zeigen:
(zip [0..] xs)
In der obigen Zeile werden Indizes für alle Elemente in der Liste angezeigt. Für die oben angegebene Eingabe würde dies folgendermaßen aussehen: [(0,1), (1,2), (2,0), (3,3), (4,0)]
(pred . snd)
Ich fand, dass dies so etwas wie pred (snd (x)) bedeutet. Meine Frage ist, ist x die Liste aus der Postleitzahl? Ich neige mich zu Ja, aber meine Vermutung ist schwach.
Als nächstes ist mein Verständnis von fst und snd. ich weiß das
fst(1,2) = 1
und
snd(1,2) = 2
Wie machen diese beiden Befehle im Code Sinn?
Mein Verständnis von Filter ist, dass es eine Liste von Elementen zurückgibt, die einer Bedingung entsprechen. Zum Beispiel,
listBiggerThen5 = filter (>5) [1,2,3,4,5,6,7,8,9,10]
würde geben [6,7,8,9,10]
Mein Verständnis von Map ist, dass es eine Funktion auf jedes Element in der Liste anwendet. Zum Beispiel,
times4 :: Int -> Int
times4 x = x * 4
listTimes4 = map times4 [1,2,3,4,5]
würde geben [4,8,12,16,20]
Wie funktioniert das insgesamt? Ich glaube, ich war umfassend in dem, was ich bisher weiß, kann die Teile aber nicht ganz zusammenfügen. Kann mir jemand helfen?
quelle
Antworten:
In Haskell möchten wir sagen, folgen Sie den Typen . In der Tat verbinden sich die Teile wie durch Drähte, die vom Typ zum entsprechenden Typ gehen:
(Erstens ist die Funktionszusammensetzung :
Die Inferenzregel für den Typ der Funktionszusammensetzung lautet:
Jetzt, )
also insgesamt
Sie haben gefragt, wie diese Teile zusammenpassen?
Das ist wie.
Mit Listenverständnis wird Ihre Funktion als geschrieben
was im Pseudocode lautet:
"Ergebnisliste enthält
i
für jeden(i,x)
inzip [0..] xs
so, dasspred x
gilt" .Dies geschieht durch Drehen der
n
Längein
wo
[a | True]
ist[a]
und[a | False]
ist[]
.quelle
Nun
pred . snd
, bedeutet\x -> pred (snd x)
. Also diese Konstrukte im Grunde eine Funktion , die ein Element bildetx
aufpred (snd x)
.Dies bedeutet also, dass der Ausdruck wie folgt aussieht:
Hier
x
wird also ein 2-Tupel von erzeugtzip
. Also, um zu wissen , wenn(0, 1)
,(1,2)
,(2, 0)
etc. werden im Ergebnis beibehalten,snd x
nehmen das zweite Element dieser 2-Tupel (so1
,2
,0
, etc.), und prüfen Sie, ob diepred
auf tha Elemente erfüllt ist oder nicht. Wenn es erfüllt ist, behält es das Element bei, andernfalls wird dieses Element (das 2-Tupel) herausgefiltert.Wenn
(== 0)
also daspred
Ice ist,filter (pred . snd) (zip [0..] xs)
enthält es die 2-Tupel[(2, 0), (4, 0)]
.Aber jetzt ist das Ergebnis eine Liste von 2 Tupeln. Wenn wir die Indizes wollen, müssen wir das 2-Tupel und das zweite Element dieser 2-Tupel irgendwie loswerden. Wir verwenden
fst :: (a, b) -> a
dafür: Dies ordnet ein 2-Tupel seinem ersten Element zu. So finden Sie eine Liste[(2, 0), (4, 0)]
,map fst [(2, 0), (4, 0)]
kehrt[2, 4]
.quelle