2016-01-11 10 views
11

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?

+4

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. –

+0

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 –

Antwort

19

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) 
+6

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

+0

@Ben Sie haben Recht. Ich habe es korrigiert. –

+0

@Ben Das mehr oder weniger erschüttert, um die formale Definition: https://en.wikipedia.org/wiki/Equivalence_of_categories#Definition – Zaaier

3

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 anichta.

+0

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

Verwandte Themen