Fwd: Work on Collections Processing Arrows?

[Apparently I forgot to hit reply-all.]
Thanks for your response, Adam.
On Tue, May 10, 2011 at 1:25 PM, Adam Megacz
class (GArrowMap a (**) u c) => GArrowJoin a (**) u c where join :: a d (c r) -> a (c d) (c r)
I like these; I think you're on the right track. The last one reminds me of concatMap.
That might be a better name for it. I was thinking in terms of a relational join.
Perhaps what you want is
gac_drop :: a (c u) u
... which is a bit like ga_cancell and ga_cancelr, but for a whole collection rather than one input at a time.
That sounds reasonable, but also looks like users would need mapA to ever leverage it. I was imagining that some models might provide mapA_ without mapA, i.e. only allowing further composition through side-effects similar to a 'for' loop in a C-family language. This is not very composition friendly, of course, but it might be easier to implement and sufficient for the job. -- | process each element in a collection, then cancel it. class (GArrow a (**) u) => GArrowMap_ a (**) u c where ga_map_ :: a d u -> a (c d) u -- | process each element in a collection; the result is subject to -- further composition. class (GArrowMap_ a (**) u c) => GArrowMap a (**) u c where ga_map :: a d r -> a (c d) (c r)
By the way, I've started [2] using type families for the "aggregate" GArrow classes like GArrowSTLC. This greatly reduces the syntactic noise in the types -- you only have one type parameter instead of four. The price is that a single type can't be an instance of these classes in more than one way (see Section 3.6.1 of [3] for why this is important).
Sounds good. I look forward to seeing where that goes. I use type and data families quite heavily in my own models - they're much friendlier for inference.
In my own case, 'c' might be representing an asynchronous or distributed, reactive collection, so the ability to restrict expressiveness is important for performance.
Certainly. The multiplicative disjunction [4] of linear logic is the "binary" version of this: (A \bindnasrepma B) is sort of like an A and a B in geographically distant locations; if you have a (Int \bindnasrepma Int) you have two Int's, but in order to (for example) add them together you must use some sort of communication primitive to get them both to the same place.
I must admit to some confusion that you likened asynchronous/distributed products used in 'synch' to 'additive conjunction' in the earlier message (help for asynchronous arrows) and the same concept to multiplicative disjunction here. Elements in such a product may exist at different times (i.e. production latencies from some initial event) as well as different locations.
It sounds like you want a sort of "collection version" of multiplicative disjunction. I bet Data Paralell Haskell's parallel array type-former (([::]) :: * -> *) would be an instance of this class.
Data Parallel Haskell is all about performance, doesn't really admit to parallel semantics or asynchronous side-effects as a result of mapping arrows across the collection. To the extent it qualifies, I suspect so would a normal list. Dave

David Barbour
you likened asynchronous/distributed products used in 'synch' to 'additive conjunction' in the earlier message (help for asynchronous arrows) and the same concept to multiplicative disjunction here.
I apologize; I transposed additive and multiplicative. Instead of this:
Adam Megacz
If you look at the corresponding multi-level language, the type of "synch"'s input (pair-of-streams) is additive conjunction [2] and its output type (stream-of-pairs) is multiplicative conjunction
I should have written: the type of "synch"'s input (pair-of-streams) is multiplicative conjunction ($\bindnasrepma$) and its output type (stream-of-pairs) is additive conjunction (&). -a
participants (2)
-
Adam Megacz
-
David Barbour