Proposal: Control.Concurrent.Async
Sjoerd Visscher
sjoerd at w3future.com
Thu Jun 14 14:12:54 CEST 2012
On Thu, 14 Jun 2012 12:42:51 0100, Simon Marlow <marlowsd at gmail.com> wrote:
On 13/06/2012 22:58, Sjoerd Visscher wrote:
> > (page1, page2, page3)
> > <- runConcurrently $ (,,)
> > <$> Concurrently (getURL "url1")
> > <*> Concurrently (getURL "url2")
> > <*> Concurrently (getURL "url3")
> >
> > More code here: https://gist.github.com/2926572
>
> I'm not sure about this. What you get with the above code is a
> strange nesting of concurrently calls, whereas what the user might
> expect is for it to behave like the existing concurrently but on
> 3-tuples instead of pairs.
Actually, that is what I expected too. So, this is not the way to use
concurrently?
concurrently3 m1 m2 m3 = (((v1, v2), v3) -> (v1, v2, v3)) <$>
concurrently (concurrently m1 m2) m3
Would this be the correct implementation then:
concurrently3 m1 m2 m3 =
withAsync m1 $ \a1 ->
withAsync m2 $ \a2 ->
withAsync m3 $ \a3 ->
wait3 a1 a2 a3
And can I then write wait3 as
wait3 a1 a2 a3 = (((v1, v2), v3) -> (v1, v2, v3)) <$> do
withAsync (waitBoth a1 a2) $ \a12 -> waitBoth a12 a3
or does it have to be:
wait3 a1 a2 a3 =
atomically $ do
v1 <- waitSTM a1 `orElse` (waitSTM a2 >> waitSTM a3 >> retry)
v2 <- waitSTM a2 `orElse` (waitSTM a3 >> retry)
v3 <- waitSTM a3
return (v1, v2, v3)
If it is this complicated, then (properly written) Applicative and
Alternative instances are certainly useful.
> I like the idea of generalising to arbitrary Traversable structures
> though. Maybe we could provide something like
>
> doConcurrently :: Traversable t => t (IO a) -> IO (t a)
>
> I haven't tried to write it, but it looks like it ought to be possible.
You'll need an Applicative instance for this anyway.
--
Sjoerd Visscher
https://github.com/sjoerdvisscher/blog
More information about the Libraries
mailing list