diff --git a/lib/src/ilist.dart b/lib/src/ilist.dart index 552e856..42ba5bc 100644 --- a/lib/src/ilist.dart +++ b/lib/src/ilist.dart @@ -290,6 +290,14 @@ abstract class IList implements TraversableMonadPlusOps { return result.map((l) => l.reverse()); } + Task> parTraverseTask(Task f(A a)) { + return map(f).foldLeft( + Task.value(nil()), + (previous, next) => + previous.both(next).map((a) => a.value1.appendElement(a.value2)) + ); + } + Evaluation> traverseEvaluation(Monoid WMi, Evaluation f(A a)) { Evaluation> result = new Evaluation(WMi, (r, s) => new Future.value(new Right(new Tuple3(WMi.zero(), s, nil())))); var current = this; diff --git a/test/ilist_test.dart b/test/ilist_test.dart index 2d13334..420dd4e 100644 --- a/test/ilist_test.dart +++ b/test/ilist_test.dart @@ -176,4 +176,22 @@ void main() { test("isEmpty", () => qc.check(forall(intILists, (IList il) => (il.length() == 0) == il.isEmpty))); + test("traverseTask is serial", () async { + final t = IList.from([1, 2, 3]).traverseTask( + (i) => Task.value(i).delayBy(const Duration(seconds: 1))); + + final result = await t.timed.run(); + + expect(result.value1 >= const Duration(seconds: 3), true); + }); + + test("parTraverseTask is concurrent", () async { + final t = IList.from([1, 2, 3, 4, 5]).parTraverseTask( + (i) => Task.value(i).delayBy(const Duration(seconds: 1))); + + final result = await t.timed.run(); + + expect(result.value1 <= const Duration(milliseconds: 1100), true); + }); + }