Open danidiaz opened 2 years ago
Come to think of it, "either the first success or the combination of all the errors" is what the proposed Monoid
instance for ConcurrentlyE
does, if you flip the error and success types (the Monoid
gives you "either the first error or the combination of all successes") 🤔
The
Applicative
instance forConcurrentlyE
behaves likeconcurrently
for successes and likerace
for errors. DoesConcurrentlyE
also admit anAlternative
instance, likeConcurrently
does?One way to define it would be making (
<|>
) behave likerace
for both successes and errors. The problem is that the instance is boring. It offers nothing you couldn't do by wrapping anIO (Either e a)
in the nomalConcurrently
.A more interesting instance would require a
Semigroup
instance on the errore
, and return either the first success or the combination of all the errors.Alas, this second definition has a problem. If
empty
is the action that waits forever, then, for any action that fails,action <|> empty
will also wait forever! This is because we must wait for all the errors, andempty
never completes. This makes uses ofData.Foldable.asum
also hang.The semigroupoids package provides
Alt
, which is "Alternative
withoutempty
". It can be used with functions likeasum1
.semigroupoids
is a big package and I'm not proposing depending on it. But perhaps noAlternative
instance forConcurrentlyE
should be defined, and anAlt
instance could be defined as an orphan in some other package instead.