2025-11-06 09:24:09 +01:00
// Copyright (c) 2023 - 2025 IBM Corp.
2025-03-01 23:07:56 +01:00
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package readerioeither
import (
2025-03-06 18:17:29 +01:00
"github.com/IBM/fp-go/v2/function"
"github.com/IBM/fp-go/v2/internal/array"
"github.com/IBM/fp-go/v2/internal/record"
2025-03-01 23:07:56 +01:00
)
2025-11-06 09:24:09 +01:00
// TraverseArray transforms an array [[]A] into [[]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[[]B]].
// This uses the default applicative behavior (parallel or sequential based on useParallel flag).
//
// Parameters:
// - f: Function that transforms each element into a ReaderIOEither
//
// Returns a function that transforms an array into a ReaderIOEither of an array.
2025-03-01 23:07:56 +01:00
func TraverseArray [ A , B any ] ( f func ( A ) ReaderIOEither [ B ] ) func ( [ ] A ) ReaderIOEither [ [ ] B ] {
2025-03-06 18:17:29 +01:00
return array . Traverse [ [ ] A ] (
Of [ [ ] B ] ,
Map [ [ ] B , func ( B ) [ ] B ] ,
Ap [ [ ] B , B ] ,
f ,
)
2025-03-01 23:07:56 +01:00
}
2025-11-06 09:24:09 +01:00
// TraverseArrayWithIndex transforms an array [[]A] into [[]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[[]B]].
// The transformation function receives both the index and the element.
//
// Parameters:
// - f: Function that transforms each element with its index into a ReaderIOEither
//
// Returns a function that transforms an array into a ReaderIOEither of an array.
2025-03-01 23:07:56 +01:00
func TraverseArrayWithIndex [ A , B any ] ( f func ( int , A ) ReaderIOEither [ B ] ) func ( [ ] A ) ReaderIOEither [ [ ] B ] {
2025-03-06 18:17:29 +01:00
return array . TraverseWithIndex [ [ ] A ] (
Of [ [ ] B ] ,
Map [ [ ] B , func ( B ) [ ] B ] ,
Ap [ [ ] B , B ] ,
f ,
)
2025-03-01 23:07:56 +01:00
}
2025-11-06 09:24:09 +01:00
// SequenceArray converts a homogeneous sequence of ReaderIOEither into a ReaderIOEither of sequence.
// This is equivalent to TraverseArray with the identity function.
//
// Parameters:
// - ma: Array of ReaderIOEither values
//
// Returns a ReaderIOEither containing an array of values.
2025-03-01 23:07:56 +01:00
func SequenceArray [ A any ] ( ma [ ] ReaderIOEither [ A ] ) ReaderIOEither [ [ ] A ] {
2025-03-06 18:17:29 +01:00
return TraverseArray ( function . Identity [ ReaderIOEither [ A ] ] ) ( ma )
2025-03-01 23:07:56 +01:00
}
2025-11-06 09:24:09 +01:00
// TraverseRecord transforms a record [map[K]A] into [map[K]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[map[K]B]].
//
// Parameters:
// - f: Function that transforms each value into a ReaderIOEither
//
// Returns a function that transforms a map into a ReaderIOEither of a map.
2025-03-01 23:07:56 +01:00
func TraverseRecord [ K comparable , A , B any ] ( f func ( A ) ReaderIOEither [ B ] ) func ( map [ K ] A ) ReaderIOEither [ map [ K ] B ] {
2025-03-06 18:17:29 +01:00
return record . Traverse [ map [ K ] A ] (
Of [ map [ K ] B ] ,
Map [ map [ K ] B , func ( B ) map [ K ] B ] ,
Ap [ map [ K ] B , B ] ,
f ,
)
2025-03-01 23:07:56 +01:00
}
2025-11-06 09:24:09 +01:00
// TraverseRecordWithIndex transforms a record [map[K]A] into [map[K]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[map[K]B]].
// The transformation function receives both the key and the value.
//
// Parameters:
// - f: Function that transforms each key-value pair into a ReaderIOEither
//
// Returns a function that transforms a map into a ReaderIOEither of a map.
2025-03-01 23:07:56 +01:00
func TraverseRecordWithIndex [ K comparable , A , B any ] ( f func ( K , A ) ReaderIOEither [ B ] ) func ( map [ K ] A ) ReaderIOEither [ map [ K ] B ] {
2025-03-06 18:17:29 +01:00
return record . TraverseWithIndex [ map [ K ] A ] (
Of [ map [ K ] B ] ,
Map [ map [ K ] B , func ( B ) map [ K ] B ] ,
Ap [ map [ K ] B , B ] ,
f ,
)
2025-03-01 23:07:56 +01:00
}
2025-11-06 09:24:09 +01:00
// SequenceRecord converts a homogeneous map of ReaderIOEither into a ReaderIOEither of map.
//
// Parameters:
// - ma: Map of ReaderIOEither values
//
// Returns a ReaderIOEither containing a map of values.
2025-03-01 23:07:56 +01:00
func SequenceRecord [ K comparable , A any ] ( ma map [ K ] ReaderIOEither [ A ] ) ReaderIOEither [ map [ K ] A ] {
2025-03-06 18:17:29 +01:00
return TraverseRecord [ K ] ( function . Identity [ ReaderIOEither [ A ] ] ) ( ma )
2025-03-01 23:07:56 +01:00
}
2025-11-06 09:24:09 +01:00
// MonadTraverseArraySeq transforms an array [[]A] into [[]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[[]B]].
// This explicitly uses sequential execution.
//
// Parameters:
// - as: The array to traverse
// - f: Function that transforms each element into a ReaderIOEither
//
// Returns a ReaderIOEither containing an array of transformed values.
2025-03-08 00:00:43 +01:00
func MonadTraverseArraySeq [ A , B any ] ( as [ ] A , f func ( A ) ReaderIOEither [ B ] ) ReaderIOEither [ [ ] B ] {
return array . MonadTraverse [ [ ] A ] (
Of [ [ ] B ] ,
Map [ [ ] B , func ( B ) [ ] B ] ,
ApSeq [ [ ] B , B ] ,
as ,
f ,
)
}
2025-11-06 09:24:09 +01:00
// TraverseArraySeq transforms an array [[]A] into [[]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[[]B]].
// This is the curried version of [MonadTraverseArraySeq] with sequential execution.
//
// Parameters:
// - f: Function that transforms each element into a ReaderIOEither
//
// Returns a function that transforms an array into a ReaderIOEither of an array.
2025-03-01 23:07:56 +01:00
func TraverseArraySeq [ A , B any ] ( f func ( A ) ReaderIOEither [ B ] ) func ( [ ] A ) ReaderIOEither [ [ ] B ] {
2025-03-06 18:17:29 +01:00
return array . Traverse [ [ ] A ] (
Of [ [ ] B ] ,
Map [ [ ] B , func ( B ) [ ] B ] ,
ApSeq [ [ ] B , B ] ,
f ,
)
2025-03-01 23:07:56 +01:00
}
// TraverseArrayWithIndexSeq uses transforms an array [[]A] into [[]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[[]B]]
func TraverseArrayWithIndexSeq [ A , B any ] ( f func ( int , A ) ReaderIOEither [ B ] ) func ( [ ] A ) ReaderIOEither [ [ ] B ] {
2025-03-08 00:00:43 +01:00
return array . TraverseWithIndex [ [ ] A ] (
Of [ [ ] B ] ,
Map [ [ ] B , func ( B ) [ ] B ] ,
ApSeq [ [ ] B , B ] ,
f ,
)
2025-03-01 23:07:56 +01:00
}
2025-11-06 09:24:09 +01:00
// SequenceArraySeq converts a homogeneous sequence of ReaderIOEither into a ReaderIOEither of sequence.
// This explicitly uses sequential execution.
//
// Parameters:
// - ma: Array of ReaderIOEither values
//
// Returns a ReaderIOEither containing an array of values.
2025-03-01 23:07:56 +01:00
func SequenceArraySeq [ A any ] ( ma [ ] ReaderIOEither [ A ] ) ReaderIOEither [ [ ] A ] {
2025-03-08 00:00:43 +01:00
return MonadTraverseArraySeq ( ma , function . Identity [ ReaderIOEither [ A ] ] )
}
// MonadTraverseRecordSeq uses transforms a record [map[K]A] into [map[K]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[map[K]B]]
func MonadTraverseRecordSeq [ K comparable , A , B any ] ( as map [ K ] A , f func ( A ) ReaderIOEither [ B ] ) ReaderIOEither [ map [ K ] B ] {
return record . MonadTraverse [ map [ K ] A ] (
Of [ map [ K ] B ] ,
Map [ map [ K ] B , func ( B ) map [ K ] B ] ,
ApSeq [ map [ K ] B , B ] ,
as ,
f ,
)
2025-03-01 23:07:56 +01:00
}
// TraverseRecordSeq uses transforms a record [map[K]A] into [map[K]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[map[K]B]]
func TraverseRecordSeq [ K comparable , A , B any ] ( f func ( A ) ReaderIOEither [ B ] ) func ( map [ K ] A ) ReaderIOEither [ map [ K ] B ] {
2025-03-08 00:00:43 +01:00
return record . Traverse [ map [ K ] A ] (
Of [ map [ K ] B ] ,
Map [ map [ K ] B , func ( B ) map [ K ] B ] ,
ApSeq [ map [ K ] B , B ] ,
f ,
)
2025-03-01 23:07:56 +01:00
}
// TraverseRecordWithIndexSeq uses transforms a record [map[K]A] into [map[K]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[map[K]B]]
func TraverseRecordWithIndexSeq [ K comparable , A , B any ] ( f func ( K , A ) ReaderIOEither [ B ] ) func ( map [ K ] A ) ReaderIOEither [ map [ K ] B ] {
2025-03-08 00:00:43 +01:00
return record . TraverseWithIndex [ map [ K ] A ] (
Of [ map [ K ] B ] ,
Map [ map [ K ] B , func ( B ) map [ K ] B ] ,
ApSeq [ map [ K ] B , B ] ,
f ,
)
2025-03-01 23:07:56 +01:00
}
// SequenceRecordSeq converts a homogeneous sequence of either into an either of sequence
func SequenceRecordSeq [ K comparable , A any ] ( ma map [ K ] ReaderIOEither [ A ] ) ReaderIOEither [ map [ K ] A ] {
2025-03-08 00:00:43 +01:00
return MonadTraverseRecordSeq ( ma , function . Identity [ ReaderIOEither [ A ] ] )
}
2025-11-06 09:24:09 +01:00
// MonadTraverseArrayPar transforms an array [[]A] into [[]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[[]B]].
// This explicitly uses parallel execution.
//
// Parameters:
// - as: The array to traverse
// - f: Function that transforms each element into a ReaderIOEither
//
// Returns a ReaderIOEither containing an array of transformed values.
2025-03-08 00:00:43 +01:00
func MonadTraverseArrayPar [ A , B any ] ( as [ ] A , f func ( A ) ReaderIOEither [ B ] ) ReaderIOEither [ [ ] B ] {
return array . MonadTraverse [ [ ] A ] (
Of [ [ ] B ] ,
Map [ [ ] B , func ( B ) [ ] B ] ,
ApPar [ [ ] B , B ] ,
as ,
f ,
)
2025-03-01 23:07:56 +01:00
}
2025-11-06 09:24:09 +01:00
// TraverseArrayPar transforms an array [[]A] into [[]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[[]B]].
// This is the curried version of [MonadTraverseArrayPar] with parallel execution.
//
// Parameters:
// - f: Function that transforms each element into a ReaderIOEither
//
// Returns a function that transforms an array into a ReaderIOEither of an array.
2025-03-01 23:07:56 +01:00
func TraverseArrayPar [ A , B any ] ( f func ( A ) ReaderIOEither [ B ] ) func ( [ ] A ) ReaderIOEither [ [ ] B ] {
2025-03-08 00:00:43 +01:00
return array . Traverse [ [ ] A ] (
Of [ [ ] B ] ,
Map [ [ ] B , func ( B ) [ ] B ] ,
ApPar [ [ ] B , B ] ,
f ,
)
2025-03-01 23:07:56 +01:00
}
// TraverseArrayWithIndexPar uses transforms an array [[]A] into [[]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[[]B]]
func TraverseArrayWithIndexPar [ A , B any ] ( f func ( int , A ) ReaderIOEither [ B ] ) func ( [ ] A ) ReaderIOEither [ [ ] B ] {
2025-03-08 00:00:43 +01:00
return array . TraverseWithIndex [ [ ] A ] (
Of [ [ ] B ] ,
Map [ [ ] B , func ( B ) [ ] B ] ,
ApPar [ [ ] B , B ] ,
f ,
)
2025-03-01 23:07:56 +01:00
}
2025-11-06 09:24:09 +01:00
// SequenceArrayPar converts a homogeneous sequence of ReaderIOEither into a ReaderIOEither of sequence.
// This explicitly uses parallel execution.
//
// Parameters:
// - ma: Array of ReaderIOEither values
//
// Returns a ReaderIOEither containing an array of values.
2025-03-01 23:07:56 +01:00
func SequenceArrayPar [ A any ] ( ma [ ] ReaderIOEither [ A ] ) ReaderIOEither [ [ ] A ] {
2025-03-08 00:00:43 +01:00
return MonadTraverseArrayPar ( ma , function . Identity [ ReaderIOEither [ A ] ] )
2025-03-01 23:07:56 +01:00
}
// TraverseRecordPar uses transforms a record [map[K]A] into [map[K]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[map[K]B]]
func TraverseRecordPar [ K comparable , A , B any ] ( f func ( A ) ReaderIOEither [ B ] ) func ( map [ K ] A ) ReaderIOEither [ map [ K ] B ] {
2025-03-08 00:00:43 +01:00
return record . Traverse [ map [ K ] A ] (
Of [ map [ K ] B ] ,
Map [ map [ K ] B , func ( B ) map [ K ] B ] ,
ApPar [ map [ K ] B , B ] ,
f ,
)
2025-03-01 23:07:56 +01:00
}
// TraverseRecordWithIndexPar uses transforms a record [map[K]A] into [map[K]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[map[K]B]]
func TraverseRecordWithIndexPar [ K comparable , A , B any ] ( f func ( K , A ) ReaderIOEither [ B ] ) func ( map [ K ] A ) ReaderIOEither [ map [ K ] B ] {
2025-03-08 00:00:43 +01:00
return record . TraverseWithIndex [ map [ K ] A ] (
Of [ map [ K ] B ] ,
Map [ map [ K ] B , func ( B ) map [ K ] B ] ,
ApPar [ map [ K ] B , B ] ,
f ,
)
}
// MonadTraverseRecordPar uses transforms a record [map[K]A] into [map[K]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[map[K]B]]
func MonadTraverseRecordPar [ K comparable , A , B any ] ( as map [ K ] A , f func ( A ) ReaderIOEither [ B ] ) ReaderIOEither [ map [ K ] B ] {
return record . MonadTraverse [ map [ K ] A ] (
Of [ map [ K ] B ] ,
Map [ map [ K ] B , func ( B ) map [ K ] B ] ,
ApPar [ map [ K ] B , B ] ,
as ,
f ,
)
2025-03-01 23:07:56 +01:00
}
2025-11-06 09:24:09 +01:00
// SequenceRecordPar converts a homogeneous map of ReaderIOEither into a ReaderIOEither of map.
// This explicitly uses parallel execution.
//
// Parameters:
// - ma: Map of ReaderIOEither values
//
// Returns a ReaderIOEither containing a map of values.
2025-03-01 23:07:56 +01:00
func SequenceRecordPar [ K comparable , A any ] ( ma map [ K ] ReaderIOEither [ A ] ) ReaderIOEither [ map [ K ] A ] {
2025-03-08 00:00:43 +01:00
return MonadTraverseRecordPar ( ma , function . Identity [ ReaderIOEither [ A ] ] )
2025-03-01 23:07:56 +01:00
}