2017-08-16 2 views
3

Früher benutzte es map und sequence mit folgenden Umsetzung zu haben:Wie Verallgemeinerung zu tun?

mapM :: Monad m => (a -> m b) -> [a] -> m [b] 

sequence :: Monad m => [m a] -> m [a] 

dann Mitwirkenden Haskell hat zu verallgemeinern:

traverse :: Applicative f => (a -> f b) -> t a -> f (t b) 

sequenceA :: (Applicative f, Traversable t) => t (f a) -> f (t a) 

Warum sie applicative über Monade wählen?

Wie werden sie die Idee zu verallgemeinern mapM und sequence? Ich möchte den Prozess verstehen, wenn ich abstrakter sein muss. Wie Sie sehen können, funktioniert mapM und sequence Arbeit nur auf die Liste, aber traverse und sequenceA sind abstrakter und arbeiten mit allen Datentyp, der Traversable umgesetzt hat.

+1

Jede Monade * ist auch * ein applicative, so dass die Wahl applicative können Sie es für andere Dinge verwenden. – MathematicalOrchid

+1

Sie nicht zu viel Sorgen um so viel wie möglich zu verallgemeinern scheitern. Oftmals ist die vollständig allgemeine Abstraktion von konkreten Anwendungen so weit entfernt, dass sie in der Praxis wenig Verwendung finden, da es einfacher wird, das Rad neu zu erfinden, als die abstrakte codierte Transformationskombinatorbibliothek mit kombinatorischer Drehübertragungsvorrichtung zu nutzen. Das Finden der richtigen Ebene der Abstraktion erfordert viel Aufwand und Fähigkeiten. (Und zumindest für theoretische Zwecke ist es sehr schön, super-abstrakte kategorientheoretische Ansätze zu regulären Aufgaben zu lesen und zu verstehen - viele lieben Haskell einfach dafür!) – chi

Antwort

2

Applicative gewählt, weil wir an der Kette Aktionen wollen, sondern Handeln, um hängt nicht von früheren Ergebnissen.

Monad: action1 >>= \resultOfAction1 -> if P(resultOfAction1) then action1 else action2 (Aktionskette kann in Abhängigkeit von Ergebnissen abweichen)

Applicative: processCombinedResult <$> action1 <*> action2 <*> action3 (Aktionskette fest)

Wenn Travers Aktion, um von Travers die interne Struktur diktiert durchqueren und hängt nicht von einander Ergebnisse . Monad kann auch verwendet werden, aber es ist restriktiver und es ist nicht möglich, Aktionen "dynamisch" zu ketten, abhängig von den Ergebnissen vorheriger Aktionen, um diese Funktionen zu implementieren. Daher wird Applicative als weniger restriktive Klasse ausgewählt, die die erforderliche Funktionalität bereitstellt.