
I was giving Control.Arrow a try for a reactive programming system. The arrows are agents that communicate by sending and returning time-varying state. Different agents may live in different 'vats' (event-driven threads) to roughly model distributed computing. For the most part, the state varies asynchronously - i.e. a file updates at a different rate than the mouse position. Anyhow, I ran into a problem: The (***) and (&&&) operations, as specified in Control.Arrow, are inherently synchronization points. Ideally one could do something like: (a1 *** a2) >>> first a3 and the output from a1 would be piped directly as input to a3, without touching a2. However, arrows also allow: (a1 *** a2) >>> arr f And, in this case, the current state of a1 and a2 must be combined into a stream of pairs so that f may be mapped over the stream. Obtaining both streams at a single place (a single vat) and time is a synchronizing operation. The synchronization operations are severely undermining the intended scalability and performance of this agent abstraction. Now, I believe I could make it work if I could somehow specialize the arrow type with aparametric structure... A (b,b') (c,c') = A b c = But I've not been able to make the Haskell type system happy with this. Type families allow some specialization, but they don't allow ambiguity or defaults. Given the 'arr' function, I must be able to instantiate an A involving any type at all. Today I explored an alternative version of Control.Arrow, using an opaque product type specialized to the arrow, but I still bumped into the issue of specializing the arrow type for this. I don't see how GADTs would help. I've been stuck on this for a couple weeks now. Ideas would be appreciated.