async icon indicating copy to clipboard operation
async copied to clipboard

Idea for Monad instance of Concurrently compatible with the Applicative Instance

Open ChristopherKing42 opened this issue 7 years ago • 2 comments

The obvious way to make Concurrently into a Monad doesn't work, since then Monad would be sequential, but Applicative would be concurrent (whereas Monad is usually supposed to be a generalization of Applicative). There is a way to make a Monad instance though that is as concurrent as possible (in particular, ap would be perfectly concurrent).

The trick is the same one used for fixIO. Given x :: Concurrently a and f :: a -> Concurrently b, we use unsafeInterleaveIO to start a thread to put x into a MVar (or TMVar or Async), and then use unsafeInterleaveIO to read the value from the variable lazily. We can then start f's action. If f needs x's value to do anything, it will be sequential. On the other hand, if f does not use x's value at all (such as in ap), it will be perfectly concurrent. It can also be anywhere in between.

I can do the code if you think this is a good concept. I just thought I'd check with you first to make sure its a good idea though.

ChristopherKing42 avatar Nov 27 '17 18:11 ChristopherKing42

Why would someone want a Monad instance for Concurrently? Can you give an example of how it might be used?

jml avatar Dec 06 '17 14:12 jml

@jml Well, for the getUrl example, we could have it fetch a list of urls from somewhere else. If the place its getting it from is slow, it would be able to start fetching the webpage of first url before it finishes getting the entire list. There are many other ways where having a Monad instance is just convenient, even if it isn't necessarily concurrent. We could also give Concurrently a MonadIO and MonadFix instance.

ChristopherKing42 avatar Dec 06 '17 19:12 ChristopherKing42