async icon indicating copy to clipboard operation
async copied to clipboard

Applicative and Alternative instances for Async

Open vwwv opened this issue 6 years ago • 5 comments

Is there a reason not to have them? If not would a PR adding them be welcomed?

vwwv avatar Oct 24 '18 22:10 vwwv

Concurrently is expected to use for those instances, but I'm not sure.

cohei avatar Oct 25 '18 06:10 cohei

I think it might be useful for some people to have both of them fit those instances, as some people (me included) prefer to use Async sometimes and Concurrent other times.

I was thinking about a potential way to implement those instances for Async, without modifying much of the previous code, could be:

  • Move the current definition of Async and related functions to an Internal package, then I think it could be done, keeping the same semantics, with something like:
module Control.Concurrent.Async  
     ( ...
     ) where

import Control.Concurrent.Async.Internal as Internal

data Async :: * -> * where
  BasicAsync       :: Internal.Async a          -> Async a
  ConcurrentAsync  :: Async (a -> b) -> Async a -> Async b 
  AlternativeAsync :: Async a        -> Async a -> Async a
  EmptyAsync       ::                           -> Async a 
  PureAsync        :: a                         -> Async a


instance Applicative Async where
  (<*>) = ConcurrentAsync
  pure  = PureAsync

instance Alternative Async where
  (<|>) = AlternativeAsync
  empty = EmptyAsync

async :: IO a -> IO (Async a)
async = fmap BasicAsync . Internal.async

cancel :: Async a -> IO ()
cancel = \case
            BasicAsync        x   -> Internal.cancel x
            ConcurrentAsync   x y -> Internal.cancel x >> Internal.cancel y
            AlternativeAsync  x y -> Internal.cancel x >> Internal.cancel y
            EmptyAsync            -> return ()
            PureAsync         _   -> return ()



.... and so on with the rest of the methods

What do you think?

vwwv avatar Oct 25 '18 16:10 vwwv

I'll send an actual PR so you can check if it is ok.

vwwv avatar Oct 25 '18 16:10 vwwv

I'm not sure I understand the motivation for this, and it adds a lot of complexity. Is there somem reason you can't use Concurrently?

simonmar avatar Oct 26 '18 07:10 simonmar

One thing I like about an Alternative instance for Async over an Alternative instance for Concurrently, is the fact that with Async <*> distributes over <|>. IMO nice to have both.

LukaJCB avatar Nov 06 '18 12:11 LukaJCB