comonads, io
Ashley Yakeley
ashley@semantic.org
Tue, 31 Dec 2002 11:54:43 -0800
In article <oqznqrnz32.fsf@premise.demon.co.uk>,
peter@premise.demon.co.uk (Peter G. Hancock) wrote:
> Frustratingly, I can't seem to grasp the intuition. I'm aware that
> the state-monad s->(s,a) has a dual state-in-context
> comonad (s,s->a). How does the side-effect manifest itself?
> The (ineffective) hints the authors give revolve around the idea that
> side-effects "derive" from the context of a program. Any other hints?
...
> I can't make the slightest sense of Kieburtz's OI co-monad, with
> commands like coGetChar :: OI Handle -> Char.
I've been wondering this myself. I always think of an object of type "IO
a" as "an imperative action that returns an a", but I have no similar
understanding for "OI a". But I think OI programs have the same
restrictions against unsafety as IO programs.
class Comonad w where
(=>>) :: w a -> (w a -> b) -> w b
(.>>) :: w a -> b -> w b
coeval :: w a -> a
instance Comonad OI where etc.
The first thing I notice is that you can't create objects of type "OI
a". I think your main program would be:
main :: OI () -> ()
Equivalent to "unsafePerformIO" would be:
unsafeOI :: OI ()
unsafeMakeOI :: a -> OI a
unsafeMakeOI a = unsafeOI .>> a
The other thing I notice is that functions of type "(Comonad w) => w a
-> b" seem to be equivalent to functions of type "(Comonad w) => w () ->
a -> b". For instance:
coGetChar :: OI Handle -> Char
coGetChar' :: OI () -> Handle -> Char
coGetChar' oi h = coGetChar (oi .>> h)
coGetChar oih = coGetChar' (oih .>> ()) (coeval oih)
You certainly can't pull anything like this with monads. This would
suggest comonads don't need to by type-constructors at all. But I'm not
sure if it's correct. Opinions?
--
Ashley Yakeley, Seattle WA