traverse
verwandelt Dinge in a Traversable
in ein Traversable
von Dingen "in" ein Applicative
, gegeben eine Funktion, die Applicative
s aus Dingen macht.
Verwenden wir Maybe
as Applicative
und listen as auf Traversable
. Zuerst brauchen wir die Transformationsfunktion:
half x = if even x then Just (x `div` 2) else Nothing
Wenn also eine Zahl gerade ist, bekommen wir die Hälfte davon (innerhalb von a Just
), sonst bekommen wir Nothing
. Wenn alles "gut" läuft, sieht es so aus:
traverse half [2,4..10]
--Just [1,2,3,4,5]
Aber...
traverse half [1..10]
-- Nothing
Der Grund ist, dass die <*>
Funktion verwendet wird, um das Ergebnis zu erstellen, und wenn eines der Argumente ist Nothing
, kehren wir Nothing
zurück.
Ein anderes Beispiel:
rep x = replicate x x
Diese Funktion generiert eine Längenliste x
mit dem Inhalt x
, zB rep 3
= [3,3,3]
. Was ist das Ergebnis von traverse rep [1..3]
?
Wir bekommen die Teilergebnisse [1]
, [2,2]
und [3,3,3]
unter Verwendung rep
. Nun ist die Semantik von Listen Applicatives
wird „alle Kombinationen nehmen“, zB (+) <$> [10,20] <*> [3,4]
ist [13,14,23,24]
.
"Alle Kombinationen" von [1]
und [2,2]
sind zweimal [1,2]
. Alle Kombinationen sind zweimal [1,2]
und [3,3,3]
sechsmal [1,2,3]
. Also haben wir:
traverse rep [1..3]
--[[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3]]