Beginnen wir mit einigen Typ-Signaturen.
%Vor% Wir können map
mit fold
simulieren, weil fold
ein universeller Operator ist ( hier) ist ein mathematischeres aber ziemlich freundliches Papier auf dieser Eigenschaft).
Ich bin sicher, dass es eine kreative Möglichkeit gibt, map
zu verwenden, um foldr
zu simulieren. Das kann sicherlich eine lustige Übung sein. Aber ich denke nicht, dass es eine geradlinige, nicht "verrückte, punktfreie" Lösung gibt, und um es zu erklären, vergessen wir foldr
für einen Moment und konzentrieren uns auf eine viel einfachere Akkumulationsfunktion:
sum == foldr (+) 0
, was bedeutet, dass foldr
implementiert sum
. Wenn wir foldr
mit map
implementieren können, können wir definitiv sum
mit map
implementieren. Können wir es tun?
Ich denke, die Signatur von sum
ist ein krachender Schlag - sum
gibt eine Int
zurück, und map
gibt immer eine Liste von etwas zurück. Vielleicht kann map
das Heavy-Lifting übernehmen, aber wir benötigen noch eine weitere Funktion vom Typ [a] -> a
, um das Endergebnis zu erhalten. In unserem Fall benötigen wir eine Funktion vom Typ [Int] -> Int
. Das ist sehr bedauerlich, denn genau das wollten wir eigentlich vermeiden.
Also ich denke, die Antwort ist: Sie können foldr
mit map
implementieren - aber es wird wahrscheinlich erfordern foldr
:)
Der einfachste Weg, um es zu betrachten, ist zu sehen, dass map
den Rücken der Liste erhält. Wenn man sich die allgemeinere fmap anschaut (was map ist, aber nicht nur für Listen, sondern für Functor
s im Allgemeinen), ist es sogar ein Gesetz, das
Es gibt viele Möglichkeiten "zu betrügen", aber in der direktesten Interpretation Ihrer Frage sind Falten einfach allgemeiner als Karten. Es gibt einen netten Trick, der in Edward Kmetts Lens-Bibliothek ziemlich oft verwendet wird. Betrachten Sie die Const
-Monade, die wie folgt definiert ist:
Nun können Sie eine Faltung in Bezug auf die monadische Kartenoperation mapM
formulieren, solange der Ergebnistyp monoid ist:
Tags und Links haskell higher-order-functions fold map-function