Monaden erhalten fmap
von Functor
typeclass. Warum brauchen comonads keine cofmap
Methode, die in einer Cofunctor
Klasse definiert ist?Warum gibt es keine "Cofunctor" -Typenklasse in Haskell?
Antwort
Functor
ist definiert als:
class Functor f where
fmap :: (a -> b) -> (f a -> f b)
Cofunctor
wie folgt definiert werden:
class Cofunctor f where
cofmap :: (b -> a) -> (f b -> f a)
Also, beide sind technisch gleich, und deshalb Cofunctor
existiert nicht. "Das duale Konzept von 'Funktor allgemein' ist immer noch 'Funktor im Allgemeinen'".
Da Functor
und Cofunctor
identisch sind, werden sowohl Monaden als auch Comonaden mit Functor
definiert. Aber lass dich nicht davon abbringen, dass Monaden und Comonaden dasselbe sind, sie sind es nicht.
A monadisch definiert (vereinfacht) als:
class Functor m => Monad where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
ob ein comonad (wiederum vereinfacht) ist:
class Functor w => Comonad where
extract :: w a -> a
extend :: (w a -> b) -> w a -> w b
Notiere die "Symmetrie".
Eine andere Sache, ein kontra Funktors wird, wie folgt definiert:
import Data.Functor.Contravariant
class Contravariant f where
contramap :: (b -> a) -> (f a -> f b)
Wäre nicht das Dual eines Funktors C -> D ein Funktor D -> C? Also ist das Duale von ** a ** funktor nicht der selbe Funktor selbst, aber das duale Konzept von "funktor im Allgemeinen" ist immer noch "funktor im Allgemeinen". Ich denke, ich spiele nur Semantik, aber die Sprache in "einem Funktor ist es selbst dual" klingt wie die Behauptung, dass einzelne Funktoren irgendwie als ihre eigene Umkehrung oder so etwas verwendbar sind. – Ben
@Ben Sie haben Recht. Ich habe es korrigiert. –
@Ben Das mehr oder weniger erschüttert, um die formale Definition: https://en.wikipedia.org/wiki/Equivalence_of_categories#Definition – Zaaier
Als Referenz
class Functor w => Comonad w where
extract :: w a -> a
duplicate :: w a -> w (w a)
extend :: (w a -> b) -> w a -> w b
instance Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
join :: Monad m => m (m a) -> m a
Beachten Sie, dass extract
gegeben und extend
Sie fmap
und duplicate
produzieren kann, und dass angesichts return
und >>=
können Sie ,produzieren, <*>
und join
. Wir können uns also nur auf pure
+ und extract
+ extend
konzentrieren.
ich denke, Sie könnten für etwas suchen, wie
class InverseFunctor f where
unmap :: (f a -> f b) -> a -> b
Da die Monad
Klasse macht es einfach, „die Dinge in“, während nur eine Art von hypothetischen Ansatz ermöglicht, „die Dinge herauszunehmen“, und Comonad
Tut etwas dagegen, klingt Ihre Anfrage zunächst sinnvoll. Es gibt jedoch eine signifikante Asymmetrie zwischen und extend
, die jedem Versuch, unmap
zu definieren, in den Weg kommt. Beachten Sie insbesondere, dass das erste Argument von >>=
den Typ m a
hat. Das zweite Argument von extend
hat den Typ w a
— nichta
.
könnten wir eine Unmap mit definieren: "unmap f = extrahieren. F. Return" und Signatur eingeben "unmap :: Monade f, Comonad f => (fa -> fb) -> a -> b" – Stratege
Eigentlich liegst du falsch: es gibt einen!
Das ist, weil ein cofunctor das gleiche wie ein Funktor ist. Es gibt keinen Unterschied zwischen den beiden. Monaden und Comonaden sind jedoch unterschiedlich. Es gibt jedoch so etwas wie einen kontravarianten Funktor, mit einer 'Contraplan'-Methode, die den Typ Contravariant f => (a -> b) -> f b -> fa 'hat. Es ist jedoch nicht dasselbe wie ein Co-Faktor. –
Meinst du "Cofunctor" als das Dual eines Funktors (der nur ein Funktor ist, da es selbst-dual ist), oder einen functor zu meinen, der kontravariant ist? http://math.stackexchange.com/questions/394472/is-cofunctor-an-accepted-term-for-contravariant-functors –