
Dan Weston wrote:
apfelmus wrote:
Luke Palmer wrote:
Isn't a type which is both a Monad and a Comonad just Identity?
(I'm actually not sure, I'm just conjecting)
Good idea, but it's not the case.
data L a = One a | Cons a (L a) -- non-empty list
Maybe I can entice you to elaborate slightly. From http://www.eyrie.org/~zednenem/2004/hsce/Control.Functor.html and Control.Comonad.html there is
---------------------------------------------------------- newtype O f g a -- Functor composition: f `O` g
instance (Functor f, Functor g) => Functor (O f g) where ... instance Adjunction f g => Monad (O g f) where ... instance Adjunction f g => Comonad (O f g) where ...
-- I assume Haskell can infer Functor (O g f) from Monad (O g f), which -- is why that is missing here?
No. But it can infer Functor (O g f) from instance (Functor f, Functor g) => Functor (O f g), (using 'g' for 'f' and 'f' for 'g').
class (Functor f, Functor g) => Adjunction f g | f -> g, g -> f where leftAdjunct :: (f a -> b) -> a -> g b rightAdjunct :: (a -> g b) -> f a -> b ----------------------------------------------------------
Functors are associative but not generally commutative. Apparently a Monad is also a Comonad if there exist left (f) and right (g) adjuncts that commute. [and only if also??? Is there a contrary example of a Monad/Comonad for which no such f and g exist?]
In the case of
data L a = One a | Cons a (L a) -- non-empty list
what are the appropriate definitions of leftAdjunct and rightAdjunct? Are they Monad.return and Comonad.extract respectively? That seems to unify a and b unnecessarily. Do they wrap bind and cobind? Are they of any practical utility?
I think you're asking the wrong question! The first question needs to be : What is "f" and what is "g" ? What are the two Functors in this case? We know that we want g `O` f to be L, because we know that the unit is return, i.e. One, and unit :: a -> O g f a otherwise known as eta :: a -> O g f a We also know there is a co-unit epsilon :: O f g a -> a, but we don't know much about that until we work out how to decompose L into two Functors. There are two standard ways to decompose a monad into two adjoint functors: the Kleisli decomposition and the Eilenberg-Moore decomposition. However, neither of these categories is a subcategory of Hask in an obvious way, so I don't immediately see how to write "f" and "g" as haskell functors. Maybe someone else can show the way :) Jules