haskellari / these

An either-or-both data type, with corresponding hybrid error/writer monad transformer.
117 stars 49 forks source link

Semialign Concurrently #199

Open Jashweii opened 4 months ago

Jashweii commented 4 months ago

I'm not sure this is useful, but it might be interesting or show up elsewhere. https://hackage.haskell.org/package/async provides:

type Concurrently :: * -> * -- newtype of IO, instances run things in parallel
instance Applicative Concurrently -- <*> = concurrently (wait for both)
instance Alternative Concurrently -- <|> = race (wait for first)

It could have

instance Semialign Concurrently -- align = ??? (wait for first, but keep both if the other is done)

When one task completes, a cancel exception is thrown to the other. But if the other is already done before that signal is received it can give back both.

With that said, this is probably not very useful since you're very unlikely to have two tasks finish within such a short overlapping time frame. Maybe if you had a long uninterruptible call this would be useful. A timed version might be useful:

-- Race, once the first completes, if the other completes within the timeout give back both results
??? :: Double {- timeout after first result -} -> IO a -> IO b -> IO (These a b)

Or you could imagine some library where a task can choose to submit a result and continue before sending a kill signal (which could achieve the timed version).

phadej commented 4 months ago

async indeed has race:: IO a -> IO b -> IO (Either a b), and the These variant could be a slight optimisation sometimes.

But I'm not sure where it belongs. Adding async dependency to these (nor semialign) doesn't feel right. Adding these dependency to async probably won't happen, but feels more correct.