@@ -200,40 +200,76 @@ func Append[T any, TS ~[]T](next func() (T, bool, error), out TS) (TS, error) {
200200 return out , nil
201201}
202202
203- // Reduce reduces the elements retrieved by the 'next' function into an one using the 'merge' function.
204- func Reduce [T any ](next func () (T , bool , error ), merger func (T , T ) T ) (out T , e error ) {
203+ // ReduceOK reduces the elements retrieved by the 'next' function into an one using the 'merge' function.
204+ // If the 'next' function returns ok=false at the first call, the zero value of 'T' type is returned.
205+ func Reduce [T any ](next func () (T , bool , error ), merge func (T , T ) T ) (T , error ) {
206+ result , _ , err := ReduceOK (next , merge )
207+ return result , err
208+ }
209+
210+ // ReduceOK reduces the elements retrieved by the 'next' function into an one using the 'merge' function.
211+ // Returns ok==false if the 'next' function returns ok=false at the first call (no more elements).
212+ func ReduceOK [T any ](next func () (T , bool , error ), merge func (T , T ) T ) (result T , ok bool , err error ) {
205213 if next == nil {
206- return out , nil
214+ return result , false , nil
215+ }
216+ if result , ok , err = next (); err != nil || ! ok {
217+ return result , ok , err
218+ }
219+ result , err = Accum (result , next , merge )
220+ return result , true , err
221+ }
222+
223+ // Reducee reduces the elements retrieved by the 'next' function into an one using the 'merge' function.
224+ // If the 'next' function returns ok=false at the first call, the zero value of 'T' type is returned.
225+ func Reducee [T any ](next func () (T , bool , error ), merge func (T , T ) (T , error )) (T , error ) {
226+ result , _ , err := ReduceeOK (next , merge )
227+ return result , err
228+ }
229+
230+ // ReduceeOK reduces the elements retrieved by the 'next' function into an one using the 'merge' function.
231+ // Returns ok==false if the 'next' function returns ok=false at the first call (no more elements).
232+ func ReduceeOK [T any ](next func () (T , bool , error ), merge func (T , T ) (T , error )) (result T , ok bool , err error ) {
233+ if next == nil {
234+ return result , false , nil
235+ }
236+ if result , ok , err = next (); err != nil || ! ok {
237+ return result , ok , err
207238 }
208- v , ok , err := next ()
209- if err != nil || ! ok {
210- return out , err
239+ result , err = Accumm (result , next , merge )
240+ return result , true , err
241+ }
242+
243+ // Accum accumulates a value by using the 'first' argument to initialize the accumulator and sequentially applying the 'merge' functon to the accumulator and each element retrieved by the 'next' function.
244+ func Accum [T any ](first T , next func () (T , bool , error ), merge func (T , T ) T ) (accumulator T , err error ) {
245+ accumulator = first
246+ if next == nil {
247+ return accumulator , nil
211248 }
212- out = v
213249 for {
214250 v , ok , err := next ()
215- if err != nil || ! ok {
216- return out , err
251+ if err != nil {
252+ return accumulator , err
253+ } else if ! ok {
254+ return accumulator , nil
217255 }
218- out = merger ( out , v )
256+ accumulator = merge ( accumulator , v )
219257 }
220258}
221259
222- // Reducee reduces the elements retrieved by the 'next' function into an one using the 'merge' function
223- func Reducee [T any ](next func () (T , bool , error ), merger func (T , T ) (T , error )) (out T , e error ) {
260+ // Accumm accumulates a value by using the 'first' argument to initialize the accumulator and sequentially applying the 'merge' functon to the accumulator and each element retrieved by the 'next' function.
261+ func Accumm [T any ](first T , next func () (T , bool , error ), merge func (T , T ) (T , error )) (accumulator T , err error ) {
262+ accumulator = first
224263 if next == nil {
225- return out , nil
226- }
227- v , ok , err := next ()
228- if err != nil || ! ok {
229- return out , err
264+ return accumulator , nil
230265 }
231- out = v
232266 for {
233267 if v , ok , err := next (); err != nil || ! ok {
234- return out , err
235- } else if out , err = merger (out , v ); err != nil {
236- return out , err
268+ return accumulator , err
269+ } else if v , err = merge (accumulator , v ); err != nil {
270+ return accumulator , err
271+ } else {
272+ accumulator = v
237273 }
238274 }
239275}
@@ -608,7 +644,7 @@ func KeyValuee[T any, K, V any](next func() (T, bool, error), keyExtractor func(
608644 return key , value , false , err
609645 } else if key , err = keyExtractor (elem ); err == nil {
610646 value , err = valExtractor (elem )
611- return key , value , err == nil , err
647+ return key , value , true , err
612648 }
613649 return key , value , false , nil
614650 }
@@ -850,13 +886,13 @@ func ToMapResolvv[T any, K comparable, V, VR any](
850886}
851887
852888// ConvertAndReduce converts each elements and merges them into one
853- func ConvertAndReduce [From , To any ](next func () (From , bool , error ), converter func (From ) To , merger func (To , To ) To ) (out To , err error ) {
854- return Reduce (Convert (next , converter ), merger )
889+ func ConvertAndReduce [From , To any ](next func () (From , bool , error ), converter func (From ) To , merge func (To , To ) To ) (out To , err error ) {
890+ return Reduce (Convert (next , converter ), merge )
855891}
856892
857893// ConvAndReduce converts each elements and merges them into one
858- func ConvAndReduce [From , To any ](next func () (From , bool , error ), converter func (From ) (To , error ), merger func (To , To ) To ) (out To , err error ) {
859- return Reduce (Conv (next , converter ), merger )
894+ func ConvAndReduce [From , To any ](next func () (From , bool , error ), converter func (From ) (To , error ), merge func (To , To ) To ) (out To , err error ) {
895+ return Reduce (Conv (next , converter ), merge )
860896}
861897
862898// Crank rertieves a next element from the 'next' function, returns the function, element, successfully flag.
0 commit comments