videos pensamiento monadas leibniz educatina dios corta biografia haskell monads category-theory

haskell - pensamiento - leibniz videos



¿Hay mónadas contravariantes? (2)

Bueno, por supuesto, es posible definirlo, pero dudo que sea de alguna utilidad.

Hay un dicho popular que dice que "la mónada es solo un monoide en una categoría de endofunctores". Lo que significa es, en primer lugar, que tenemos una categoría de endofunctores (es decir, funtores (covariantes) de alguna categoría a sí mismo), y más aún, tenemos cierta multiplicación en estos endofunctores (en este caso, composición). Y luego la mónada encaja en un marco general del que no tenemos que preocuparnos ahora. El punto es que no hay "multiplicación" de funtores contravariantes. La composición de dos funtores covariantes es nuevamente un funtor covariante; pero la composición de dos funtores contravariantes no es un funtor contravariante (más bien es un funtor covariante, por lo tanto, una bestia totalmente diferente).

Por lo tanto, las "mónadas contravariantes" realmente no tienen sentido.

Los funcionalizadores pueden ser covariantes y contravariantes. ¿Puede esta dualidad covariante / contravariante también aplicarse a las mónadas?

Algo como:

class Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b class ContraMonad m where return :: a -> m a contrabind :: m a -> (b -> m a) -> m b

¿Tiene sentido la clase ContraMonad ? ¿Algún ejemplo?


Un funtor contravariante es un funtor de una categoría a su categoría opuesta , es decir, de una categoría a otra (aunque está estrechamente relacionado). OTOH, una mónada es ante todo un endofunctor, es decir, de una categoría en sí misma . Entonces no puede ser contravariante.

Este tipo de cosas siempre tiende a ser mucho más claro cuando se considera la definición "matemática fundamental" de las mónadas:

class Functor m => Monad m where pure :: a -> m a join :: m (m a) -> m a

Como ves, realmente no hay flechas allí que puedas cambiar en el resultado, como hiciste con contrabind . Claro que hay

class Functor n => Comonad n where extract :: n a -> a duplicate :: n a -> n (n a)

pero los comonads siguen siendo funtores covariantes.

A diferencia de las mónadas, los aplicativos ( funtores monoidal ) no necesitan ser endofunctores, por lo que creo que se pueden cambiar. Empecemos por la definición “fundamental”:

class Functor f => Monoidal f where pureUnit :: () -> f () fzipWith :: ((a,b)->c) -> (f a, f b)->f c -- I avoid currying to make it clear what the arrows are.

(Ejercicio: definir una instancia Applicative derivada en términos de esto, y viceversa)

Dando la vuelta

class Contravariant f => ContraApp f where pureDisunit :: f () -> () fcontraunzip :: ((a,b)->c) -> f c->(f a, f b) -- I''m not sure, maybe this should -- be `f c -> Either (f a) (f b)` instead.

No tengo idea de lo útil que sería. pureDisunit ciertamente no es útil, porque su única implementación es siempre const () .

Intentemos escribir la instancia obvia:

newtype Opp a b = Opp { getOpp :: b -> a } instance Contravariant (Opp a) where contramap f (Opp g) = Opp $ g . f instance ContraApp (Opp a) where pureDisunit = const () fcontraunzip z (Opp g) = (Opp $ /a -> ???, Opp $ /b -> ???) -- `z` needs both `a` and `b`, can''t get it!

No creo que esto sea útil, aunque es posible que puedas definirlo con algo así como una inteligente recursión de nudos.

Lo que podría ser más interesante es un funtor co-monoidal contravariante , pero esto se vuelve demasiado extraño para mí en este momento.