Hi, does Arrow have function like `(List<IO<...
# arrow
g
Hi, does Arrow have function like
(List<IO<T>>) -> IO<T>
which runs each IO in
List<IO<T>>
in parallel and waiting for the first result?
Just found the solution:
Copy code
reduce { acc, io -> 
        coroutineContext.raceN(acc, io).map { it.fold(::identity, ::identity) }
    }
but maybe there is may be better solution
s
@genovich there is no such method out of the box. There is a slight improvement over your snippet which uses
never
and
fold
instead. It uses an
IO
that never finishes as an empty value for the list. Such that
emptyList().race()
would result in a race that never finishes, instead of blowing up like
reduce
.
Copy code
fun <A> List<IO<A>>.race(): IO<A> =
  foldRight(never<A>()) { acc, io 
     IO.raceN(acc, io)
       .map { it.fold(::identity, ::identity) }
  }
Keep in mind that the `IO`s are scheduled in order, so the once scheduled first might have a slight advantage over the last onces being scheduled. Which might also depend on in which
coroutineContext
you launch it etc.
👍 2
g
Thanks!
j
Wow, that's a really cool way to do it! ... using
never
@simon.vergauwen
👍 1
g
Is it ok to define monoid and use
list.fold(monoid)
in this case?
s
Yes, that's definitely possible and I think it will be lawfull as well. It would need a special testing strategy tho since
Monoid#empty
is
never
finishing