Dies ist eine spekulative Antwort. Mit Vorsicht fortfahren.
Lassen Sie uns zuerst KleisliFunctor
betrachten, auf dem bind artigen Pfeil Mapping konzentriert:
class (Monad m, Functor f) => KleisliFunctor m f where
kmap :: (a -> m b) -> f a -> f b
Damit dies tatsächlich ein Funktor von der Kleisli Kategorie von m
zu sein Hask, kmap
die relevanten folgen hat Funktors Gesetze:
-- Mapping the identity gives identity (in the other category).
kmap return = id
-- Mapping a composed arrow gives a composed arrow (in the other category).
kmap (g <=< f) = kmap g . kmap f
Die Tatsache, dass es zwei Functor
s beteiligt macht die Sache ein wenig ungewöhnlich, b ut nicht unvernünftig - zum Beispiel gelten die Gesetze für mapMaybe
, das ist das erste konkrete Beispiel, das der KleisliFunctor
Post darauf anspielt.
Was Absorb
, werde ich das bind-ähnliches Verfahren aus Gründen der Klarheit Flip:
class (Functor f, Monad m) => Absorb f m where
(~<<) :: (a -> m b) -> f a -> m b
Wenn wir für etwas analog zu KleisliFunctor
suchen, eine Frage, die sofort stellt, ist, welche Kategorie Funktionen haben würde vom Typ f a -> m b
als Pfeile. Es kann sicherlich nicht sein Hask, da seine Identität (des Typs f a -> m a
) nicht id
sein kann. Wir müssten nicht nur Identität, sondern auch Zusammensetzung herausfinden. Für etwas, das nicht ganz im Gegensatz zu Monad
ist ...
idAbsorb :: f a -> m a
compAbsorb :: (f b -> m c) -> (f a -> m b) -> (f a -> m c)
... die einzige plausible Sache, die ich Recht jetzt denken kann, ist mit einer Monade morphism als idAbsorb
und unter Verwendung eines zweiten Monade morphism in der entgegengesetzten Richtung (dh ist, von m
zu f
), so dass compAbsorb
durch Anwendung der ersten Funktion implementiert werden kann, dann zurück zu f
gehen und schließlich die zweite Funktion anwenden. Wir müssten das herausfinden, um zu sehen, ob meine Annahmen angemessen sind, ob dieser Ansatz funktioniert und ob er zu etwas führt, das für Ihre Zwecke nützlich ist.
Haben Sie einen bestimmten Beispieltyp, der eine 'Absorb'-Instanz zulässt, aber keine ausreichend mächtigen Standardinstanzen zur Implementierung von '(>> ~)' und 'ajoin'? – leftaroundabout
@leftaroundabout, ich brauche 'Absorb', um eine generalisierte monadische Faltung zu implementieren, die es erlaubt, einen Akkumulator im' f'-Funktor zu halten, aber das Ergebnis in der 'm'-Monade zurückgibt. Siehe z.B. [this] (https://github.com/effectify/prefolds/blob/374257b12f9a2af752862addafe456cded9c0efb/test/Main.hs#L297). – user3237465