
So in the result of (a >>= f), the first element is taken from the first element of applying f to the first element of a; the second element is the second element in the result of applying f to the second element of a; and so on. Off the top of my head I am not sure what this corresponds to in terms of agents or where it would be useful, but I'm sure it must correspond to something interesting. In short, join corresponds to continuously sampling a stream of streams. In other words, it turns a higher-order stream into a dynamic data-flow network. That's exactly what the Elerea library [1] is good for: it allows you to do this in constant time instead of the quadratic cost of the pure implementation, but it forces you to traverse streams sequentially -- fortunately, that's exactly what you want to do most of the time. There is also a paper behind the library, which might help a bit in getting a clearer picture [2] (the paper also has an updated version in the process of being published).
Gergely [1] http://hackage.haskell.org/package/elerea [2] http://sgate.emt.bme.hu/documents/patai/publications/PataiWFLP2010.pdf -- http://www.fastmail.fm - One of many happy users: http://www.fastmail.fm/docs/quotes.html