From 31624b5314829089f5fb7572b8e67d27dba91571 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Thu, 12 Oct 2023 17:50:51 +0200 Subject: [PATCH] Helper method to turn iterator to a Vector (#8035) --- .../Base/0.0.0-dev/src/Data/Vector.enso | 25 +++++++++++++++++ test/Tests/src/Data/Vector_Spec.enso | 28 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Vector.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Vector.enso index 717621d2dbe0..3a1c620f3fa8 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Vector.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Vector.enso @@ -71,6 +71,31 @@ type Vector a new : Integer -> (Integer -> Any) -> Vector Any new length constructor = Array_Like_Helpers.vector_from_function length constructor + ## PRIVATE + ADVANCED + Collects elements of a sequence into a new vector. Various structures can be + converted into vector of elements. This helper methods allows to do so in an + iterative fashion. Enough to describe how to extract value from current item + and how to advance to next item. + + Arguments: + - seq: the sequence to process. + - element: A function taking the `seq` and follow ups and extracting the value to put into the vector + - next: A function to advance to next _item_ of the sequence + - limit: maximal number of elements to collect. Defaults to infinity. + - stop_at: optional function like `(_==List.Nil)` to check for _end of sequence condition_. + By default checks for `Nothing` being the terminal element of a collection. + + > Example + Turn a list into a vector. + Vector.collect (List.Cons 1 <| List.Cons 2 <| List.Nil) .x .xs stop_at=(_==List.Nil) + collect seq element:(Any -> Any) next:(Any->Any) limit:(Integer|Nothing)=Nothing stop_at:(Any->Boolean)=(_==Nothing) = + b = Vector.new_builder (if limit.is_nothing then 10 else limit) + iterate item remaining = if remaining == 0 || (stop_at item) then b.to_vector else + b.append <| element item + @Tail_Call iterate (next item) (if remaining.is_nothing then Nothing else remaining-1) + iterate seq limit + ## PRIVATE ADVANCED diff --git a/test/Tests/src/Data/Vector_Spec.enso b/test/Tests/src/Data/Vector_Spec.enso index 237d7d79e82c..cfc3240dfeaf 100644 --- a/test/Tests/src/Data/Vector_Spec.enso +++ b/test/Tests/src/Data/Vector_Spec.enso @@ -813,6 +813,20 @@ spec = e.length . should_equal 1 b.at 0 . should_equal 32 + Test.specify "Vector.collect lazy" <| + seq = Fib.sequence + seq.take 5 . should_equal [1, 1, 2, 3, 5] + + Test.specify "Vector.collect empty list" <| + l = List.Nil + v = Vector.collect l .x .xs limit=30 stop_at=(_==List.Nil) + v . should_equal [] + + Test.specify "Vector.collect finite" <| + l = List.Cons 1 <| List.Cons 2 <| List.Cons 3 <| List.Nil + v = Vector.collect l .x .xs limit=30 stop_at=(_==List.Nil) + v . should_equal [1, 2, 3] + Test.group "Vector/Array equality" <| v1 = [1, 2, 3] a1 = v1.to_array @@ -865,4 +879,18 @@ spec = sliced_array = sliced_vector.to_array sliced_array + + +type Fib + Number n:Integer ~next:Fib + + take self limit:Integer = Vector.collect self .n .next limit + + sequence = + sum_two seq = Fib.Number seq.n+seq.next.n (sum_two seq.next) + start = Fib.Number 1 <| Fib.Number 1 (sum_two start) + start + + + main = Test_Suite.run_main spec