[Apparently I forgot to hit reply-all.] Thanks for your response, Adam.
On Tue, May 10, 2011 at 1:25 PM, Adam Megacz <meg...@cs.berkeley.edu> wrote: > > 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
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe