On Sat, Jul 9, 2011 at 3:58 AM, Henning Thielemann <lemming@henning-thielemann.de> wrote:

My stream processors are not Arrows, because 'first' cannot be implemented. However, 'arr' and '.' can be implemented.

Currently I have build the two tasks into one stream processor. I would like to split these into two processors. This looks difficult to me, since the first stream processor (for management of pressed keys) must provide a state (the set of pressed keys) whenever the second stream processor (for clock generation) needs it.

For event-stream processing, ArrowChoice is closer to what you need, i.e. using a sum type instead of a product type. This isn't a new idea: Yampa is pretty much implemented that way. It seems your current 'streamed' package does not provide equivalent functions, so I'll just provide a list of useful operators: 

   type :+: = Either -- in the simple case

   left :: T a a -> T (a :+: b) (a' :+: b) 
   right :: T b b' -> T (a :+: b) (a:+: b')
   merge :: T (a :+: a) a
   mirror :: T (a :+: b) (b :+: a)
   assocl :: T (a :+: (b :+: c)) ((a :+: b) :+: c)
   assocr :: T ((a :+: b) :+: c) (a :+: (b :+: c))
   inl :: T a (a :+: b)
   inr :: T b (a :+: b)
   Control.Category (id, (.))

   (|||) :: T a c -> T b c -> T (a :+: b) c
   (|||) f g = (f +++ g) >>> merge

   (+++) :: T a a' -> T b b' -> T (a :+: b) (a' :+: b')
   (+++) f g = left f >>> right g

This will give you that extra dimension of composability you seem to be wishing for, allow you to split events across separate processors.

Regards,

David