diff --git a/src/tests/util/list.cpp b/src/tests/util/list.cpp index 5efde610c..75d4c3a7c 100644 --- a/src/tests/util/list.cpp +++ b/src/tests/util/list.cpp @@ -187,6 +187,21 @@ static void tst14() { lean_assert_eq(filter(l, [](int i) { return i % 3 == 0; }), list({3, 6})); } +static list range(int l, int u) { + if (l > u) + return list(); + else + return cons(l, range(l+1, u)); +} + +static void tst15() { + list l({1, 2, 3, 4}); + std::cout << map_append(l, [](int i) { return range(1, i); }) << "\n"; + lean_assert_eq(map_append(l, [](int i) { return range(1, i); }), list({1, 1, 2, 1, 2, 3, 1, 2, 3, 4})); + lean_assert_eq(map_append(l, [](int i) { return i == 2 ? list({2, 2, 2}) : list(i); }), + list({1, 2, 2, 2, 3, 4})); +} + int main() { tst1(); tst2(); @@ -202,5 +217,6 @@ int main() { tst12(); tst13(); tst14(); + tst15(); return has_violations() ? 1 : 0; } diff --git a/src/util/list_fn.h b/src/util/list_fn.h index de4a4da86..814cd31a9 100644 --- a/src/util/list_fn.h +++ b/src/util/list_fn.h @@ -204,6 +204,18 @@ list map_filter(list const & l, F && f) { } } +template +list map_append(list const & l, F && f) { + if (is_nil(l)) { + return l; + } else { + buffer tmp; + for (auto const & v : l) + to_buffer(f(v), tmp); + return to_list(tmp.begin(), tmp.end()); + } +} + /** \brief Semantically equivalent to \c map, but it tries to reuse list cells. The elements are compared using the predicate \c eq.