[Haskell] Paper: The essence of dataflow programming

Einar Karttunen ekarttun at cs.helsinki.fi
Mon Sep 26 03:45:25 EDT 2005


On 26.09 01:01, David Menendez wrote:
> We'll also define the injection combinator from Kieburtz's paper[1]:
> 
> > (.>>) :: Functor d => d a -> b -> d b
> > d .>> a = fmap (const a) d

We add some nice combinators:


(>>-) :: Comonad co => (co a -> co b) -> (co b -> co c) -> co a -> co c
a >>- b = b . a
infixr >>-

(>>--) :: Comonad co => (co a -> co b) -> (b -> co b -> co c) -> co a -> co c
a >>-- b = \co -> let x = a co in b (counit x) x
infixr >>--

coreturn v = cobind (const v)


And define the simple state comonad:


data StateC st a = StateC (st -> a) st

instance Comonad (StateC st) where
  counit (StateC f v)     = f v
  cobind fun (StateC f v) = StateC (\v -> fun (StateC f v)) v

get :: StateC st a -> StateC st st
get (StateC _ st) = StateC id st

set :: st -> StateC st a -> StateC st a
set new (StateC fun _) = StateC fun new

modify :: (c -> c) -> StateC c a -> StateC c a
modify mutator (StateC fun st) = StateC fun $ mutator st

runStateC fun v0 = let StateC a b = fun (StateC id v0) in (a b,b)


Now we can write comonadic code like monadic code:

foobar = get >>-- \x -> coreturn (3*x)

test3 = get         >>-- \x ->
        set 15      >>-
        foobar      >>-- \y ->
        set x       >>-
        coreturn (show y)


This looks very much like monadic code written with >> and >>=.

A general Functor instance is easy (but non-haskell98):


instance Comonad w => Functor w where
  fmap f = cobind (f . counit)


- Einar Karttunen


More information about the Haskell mailing list