Thomvis / BrightFutures

Write great asynchronous code in Swift using futures and promises
MIT License
1.9k stars 184 forks source link

traverse for futures of list results #163

Closed Tvede-dk closed 7 years ago

Tvede-dk commented 7 years ago

The Issue:

Suggestion Either the behavior could / should be in a closure, and or a seperate function, that does not do the wrapping (but only work with futures of Future<[T], E> ). ( the changes to create such a function is to remove the [], and change the where clause such that A.Value.Value == [U] )

Thomvis commented 7 years ago

What do you want the Future<[T],E>s to combine into? Can you perhaps provide a piece of code that illustrates the issue? Thanks!

Tvede-dk commented 7 years ago

Ahh I see, so its fairly simple **. I want to combine a lot of futures, of the type Future<[T],E>. I still expect the result to be Future<[T],E>. (this fits for example nicely with the composite pattern). I have only had the time to write the traverse function this way;

public extension Sequence {

public func traverseList<U, E, A:AsyncType>(_ context: @escaping ExecutionContext = DispatchQueue.global().context,
                                           _ f: (Iterator.Element) -> A) -> Future<[U], E> where A.Value: ResultProtocol, A.Value.Value == [U], A.Value.Error == E {
   return map(f).fold(context, zero: [U]()) { (list: [U], elem: [U]) -> [U] in  
                                return list + elem
                             }
   }
}
Thomvis commented 7 years ago

Thanks for the example. I think you can achieve this behavior quite nicely by combining the existing sequence() function with the Swift standard library way of flattening arrays. So something like:

arrayOfFutureArrays.sequence().map { $0.joined() }

This gives you a Future<FlattenBidirectionalCollection<Array<E>>>. Other ways of performing the second step can be found here.

Would this work for you?