[Haskell-cafe] Fwd: Work on Collections Processing Arrows?

David Barbour dmbarbour at gmail.com
Wed May 11 17:15:16 CEST 2011

[Apparently I forgot to hit reply-all.]

Thanks for your response, Adam.

On Tue, May 10, 2011 at 1:25 PM, Adam Megacz <megacz at 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

> 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

> > 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.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20110511/85342f49/attachment.htm>

More information about the Haskell-Cafe mailing list