2025-11-06 09:27:00 +01:00
// Copyright (c) 2023 - 2025 IBM Corp.
// 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.
2025-11-11 11:01:49 +01:00
package readerioresult
2025-11-06 09:27:00 +01:00
import (
2025-11-15 12:13:37 +01:00
"github.com/IBM/fp-go/v2/array"
2025-11-06 09:27:00 +01:00
"github.com/IBM/fp-go/v2/function"
"github.com/IBM/fp-go/v2/internal/record"
)
2025-11-11 11:01:49 +01:00
// TraverseArray transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]].
2025-11-06 09:27:00 +01:00
// This uses the default applicative behavior (parallel or sequential based on useParallel flag).
//
// Parameters:
2025-11-11 11:01:49 +01:00
// - f: Function that transforms each element into a ReaderIOResult
2025-11-06 09:27:00 +01:00
//
2025-11-11 11:01:49 +01:00
// Returns a function that transforms an array into a ReaderIOResult of an array.
2025-11-07 14:35:46 +01:00
func TraverseArray [ A , B any ] ( f Kleisli [ A , B ] ) Kleisli [ [ ] A , [ ] B ] {
2025-11-15 12:13:37 +01:00
return array . Traverse (
2025-11-06 09:27:00 +01:00
Of [ [ ] B ] ,
Map [ [ ] B , func ( B ) [ ] B ] ,
Ap [ [ ] B , B ] ,
f ,
)
}
2025-11-11 11:01:49 +01:00
// TraverseArrayWithIndex transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]].
2025-11-06 09:27:00 +01:00
// The transformation function receives both the index and the element.
//
// Parameters:
2025-11-11 11:01:49 +01:00
// - f: Function that transforms each element with its index into a ReaderIOResult
2025-11-06 09:27:00 +01:00
//
2025-11-11 11:01:49 +01:00
// Returns a function that transforms an array into a ReaderIOResult of an array.
func TraverseArrayWithIndex [ A , B any ] ( f func ( int , A ) ReaderIOResult [ B ] ) Kleisli [ [ ] A , [ ] B ] {
2025-11-15 12:13:37 +01:00
return array . TraverseWithIndex (
2025-11-06 09:27:00 +01:00
Of [ [ ] B ] ,
Map [ [ ] B , func ( B ) [ ] B ] ,
Ap [ [ ] B , B ] ,
f ,
)
}
2025-11-11 11:01:49 +01:00
// SequenceArray converts a homogeneous sequence of ReaderIOResult into a ReaderIOResult of sequence.
2025-11-06 09:27:00 +01:00
// This is equivalent to TraverseArray with the identity function.
//
// Parameters:
2025-11-11 11:01:49 +01:00
// - ma: Array of ReaderIOResult values
2025-11-06 09:27:00 +01:00
//
2025-11-11 11:01:49 +01:00
// Returns a ReaderIOResult containing an array of values.
func SequenceArray [ A any ] ( ma [ ] ReaderIOResult [ A ] ) ReaderIOResult [ [ ] A ] {
return TraverseArray ( function . Identity [ ReaderIOResult [ A ] ] ) ( ma )
2025-11-06 09:27:00 +01:00
}
2025-11-11 11:01:49 +01:00
// TraverseRecord transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]].
2025-11-06 09:27:00 +01:00
//
// Parameters:
2025-11-11 11:01:49 +01:00
// - f: Function that transforms each value into a ReaderIOResult
2025-11-06 09:27:00 +01:00
//
2025-11-11 11:01:49 +01:00
// Returns a function that transforms a map into a ReaderIOResult of a map.
2025-11-07 14:35:46 +01:00
func TraverseRecord [ K comparable , A , B any ] ( f Kleisli [ A , B ] ) Kleisli [ map [ K ] A , map [ K ] B ] {
2025-11-06 09:27:00 +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-11-11 11:01:49 +01:00
// TraverseRecordWithIndex transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]].
2025-11-06 09:27:00 +01:00
// The transformation function receives both the key and the value.
//
// Parameters:
2025-11-11 11:01:49 +01:00
// - f: Function that transforms each key-value pair into a ReaderIOResult
2025-11-06 09:27:00 +01:00
//
2025-11-11 11:01:49 +01:00
// Returns a function that transforms a map into a ReaderIOResult of a map.
func TraverseRecordWithIndex [ K comparable , A , B any ] ( f func ( K , A ) ReaderIOResult [ B ] ) Kleisli [ map [ K ] A , map [ K ] B ] {
2025-11-06 09:27:00 +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-11-11 11:01:49 +01:00
// SequenceRecord converts a homogeneous map of ReaderIOResult into a ReaderIOResult of map.
2025-11-06 09:27:00 +01:00
//
// Parameters:
2025-11-11 11:01:49 +01:00
// - ma: Map of ReaderIOResult values
2025-11-06 09:27:00 +01:00
//
2025-11-11 11:01:49 +01:00
// Returns a ReaderIOResult containing a map of values.
func SequenceRecord [ K comparable , A any ] ( ma map [ K ] ReaderIOResult [ A ] ) ReaderIOResult [ map [ K ] A ] {
return TraverseRecord [ K ] ( function . Identity [ ReaderIOResult [ A ] ] ) ( ma )
2025-11-06 09:27:00 +01:00
}
2025-11-11 11:01:49 +01:00
// MonadTraverseArraySeq transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]].
2025-11-06 09:27:00 +01:00
// This explicitly uses sequential execution.
//
// Parameters:
// - as: The array to traverse
2025-11-11 11:01:49 +01:00
// - f: Function that transforms each element into a ReaderIOResult
2025-11-06 09:27:00 +01:00
//
2025-11-11 11:01:49 +01:00
// Returns a ReaderIOResult containing an array of transformed values.
func MonadTraverseArraySeq [ A , B any ] ( as [ ] A , f Kleisli [ A , B ] ) ReaderIOResult [ [ ] B ] {
2025-11-11 15:24:45 +01:00
return array . MonadTraverse (
2025-11-06 09:27:00 +01:00
Of [ [ ] B ] ,
Map [ [ ] B , func ( B ) [ ] B ] ,
ApSeq [ [ ] B , B ] ,
as ,
f ,
)
}
2025-11-11 11:01:49 +01:00
// TraverseArraySeq transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]].
2025-11-06 09:27:00 +01:00
// This is the curried version of [MonadTraverseArraySeq] with sequential execution.
//
// Parameters:
2025-11-11 11:01:49 +01:00
// - f: Function that transforms each element into a ReaderIOResult
2025-11-06 09:27:00 +01:00
//
2025-11-11 11:01:49 +01:00
// Returns a function that transforms an array into a ReaderIOResult of an array.
2025-11-07 14:35:46 +01:00
func TraverseArraySeq [ A , B any ] ( f Kleisli [ A , B ] ) Kleisli [ [ ] A , [ ] B ] {
2025-11-15 12:13:37 +01:00
return array . Traverse (
2025-11-06 09:27:00 +01:00
Of [ [ ] B ] ,
Map [ [ ] B , func ( B ) [ ] B ] ,
ApSeq [ [ ] B , B ] ,
f ,
)
}
2025-11-11 11:01:49 +01:00
// TraverseArrayWithIndexSeq uses transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]]
func TraverseArrayWithIndexSeq [ A , B any ] ( f func ( int , A ) ReaderIOResult [ B ] ) Kleisli [ [ ] A , [ ] B ] {
2025-11-15 12:13:37 +01:00
return array . TraverseWithIndex (
2025-11-06 09:27:00 +01:00
Of [ [ ] B ] ,
Map [ [ ] B , func ( B ) [ ] B ] ,
ApSeq [ [ ] B , B ] ,
f ,
)
}
2025-11-11 11:01:49 +01:00
// SequenceArraySeq converts a homogeneous sequence of ReaderIOResult into a ReaderIOResult of sequence.
2025-11-06 09:27:00 +01:00
// This explicitly uses sequential execution.
//
// Parameters:
2025-11-11 11:01:49 +01:00
// - ma: Array of ReaderIOResult values
2025-11-06 09:27:00 +01:00
//
2025-11-11 11:01:49 +01:00
// Returns a ReaderIOResult containing an array of values.
func SequenceArraySeq [ A any ] ( ma [ ] ReaderIOResult [ A ] ) ReaderIOResult [ [ ] A ] {
return MonadTraverseArraySeq ( ma , function . Identity [ ReaderIOResult [ A ] ] )
2025-11-06 09:27:00 +01:00
}
2025-11-11 11:01:49 +01:00
// MonadTraverseRecordSeq uses transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]
func MonadTraverseRecordSeq [ K comparable , A , B any ] ( as map [ K ] A , f Kleisli [ A , B ] ) ReaderIOResult [ map [ K ] B ] {
2025-11-11 15:24:45 +01:00
return record . MonadTraverse (
2025-11-06 09:27:00 +01:00
Of [ map [ K ] B ] ,
Map [ map [ K ] B , func ( B ) map [ K ] B ] ,
ApSeq [ map [ K ] B , B ] ,
as ,
f ,
)
}
2025-11-11 11:01:49 +01:00
// TraverseRecordSeq uses transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]
2025-11-07 14:35:46 +01:00
func TraverseRecordSeq [ K comparable , A , B any ] ( f Kleisli [ A , B ] ) Kleisli [ map [ K ] A , map [ K ] B ] {
2025-11-06 09:27:00 +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-11-11 11:01:49 +01:00
// TraverseRecordWithIndexSeq uses transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]
func TraverseRecordWithIndexSeq [ K comparable , A , B any ] ( f func ( K , A ) ReaderIOResult [ B ] ) Kleisli [ map [ K ] A , map [ K ] B ] {
2025-11-06 09:27:00 +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 ,
)
}
// SequenceRecordSeq converts a homogeneous sequence of either into an either of sequence
2025-11-11 11:01:49 +01:00
func SequenceRecordSeq [ K comparable , A any ] ( ma map [ K ] ReaderIOResult [ A ] ) ReaderIOResult [ map [ K ] A ] {
return MonadTraverseRecordSeq ( ma , function . Identity [ ReaderIOResult [ A ] ] )
2025-11-06 09:27:00 +01:00
}
2025-11-11 11:01:49 +01:00
// MonadTraverseArrayPar transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]].
2025-11-06 09:27:00 +01:00
// This explicitly uses parallel execution.
//
// Parameters:
// - as: The array to traverse
2025-11-11 11:01:49 +01:00
// - f: Function that transforms each element into a ReaderIOResult
2025-11-06 09:27:00 +01:00
//
2025-11-11 11:01:49 +01:00
// Returns a ReaderIOResult containing an array of transformed values.
func MonadTraverseArrayPar [ A , B any ] ( as [ ] A , f Kleisli [ A , B ] ) ReaderIOResult [ [ ] B ] {
2025-11-11 15:24:45 +01:00
return array . MonadTraverse (
2025-11-06 09:27:00 +01:00
Of [ [ ] B ] ,
Map [ [ ] B , func ( B ) [ ] B ] ,
ApPar [ [ ] B , B ] ,
as ,
f ,
)
}
2025-11-11 11:01:49 +01:00
// TraverseArrayPar transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]].
2025-11-06 09:27:00 +01:00
// This is the curried version of [MonadTraverseArrayPar] with parallel execution.
//
// Parameters:
2025-11-11 11:01:49 +01:00
// - f: Function that transforms each element into a ReaderIOResult
2025-11-06 09:27:00 +01:00
//
2025-11-11 11:01:49 +01:00
// Returns a function that transforms an array into a ReaderIOResult of an array.
2025-11-07 14:35:46 +01:00
func TraverseArrayPar [ A , B any ] ( f Kleisli [ A , B ] ) Kleisli [ [ ] A , [ ] B ] {
2025-11-15 12:13:37 +01:00
return array . Traverse (
2025-11-06 09:27:00 +01:00
Of [ [ ] B ] ,
Map [ [ ] B , func ( B ) [ ] B ] ,
ApPar [ [ ] B , B ] ,
f ,
)
}
2025-11-11 11:01:49 +01:00
// TraverseArrayWithIndexPar uses transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]]
func TraverseArrayWithIndexPar [ A , B any ] ( f func ( int , A ) ReaderIOResult [ B ] ) Kleisli [ [ ] A , [ ] B ] {
2025-11-15 12:13:37 +01:00
return array . TraverseWithIndex (
2025-11-06 09:27:00 +01:00
Of [ [ ] B ] ,
Map [ [ ] B , func ( B ) [ ] B ] ,
ApPar [ [ ] B , B ] ,
f ,
)
}
2025-11-11 11:01:49 +01:00
// SequenceArrayPar converts a homogeneous sequence of ReaderIOResult into a ReaderIOResult of sequence.
2025-11-06 09:27:00 +01:00
// This explicitly uses parallel execution.
//
// Parameters:
2025-11-11 11:01:49 +01:00
// - ma: Array of ReaderIOResult values
2025-11-06 09:27:00 +01:00
//
2025-11-11 11:01:49 +01:00
// Returns a ReaderIOResult containing an array of values.
func SequenceArrayPar [ A any ] ( ma [ ] ReaderIOResult [ A ] ) ReaderIOResult [ [ ] A ] {
return MonadTraverseArrayPar ( ma , function . Identity [ ReaderIOResult [ A ] ] )
2025-11-06 09:27:00 +01:00
}
2025-11-11 11:01:49 +01:00
// TraverseRecordPar uses transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]
2025-11-07 14:35:46 +01:00
func TraverseRecordPar [ K comparable , A , B any ] ( f Kleisli [ A , B ] ) Kleisli [ map [ K ] A , map [ K ] B ] {
2025-11-06 09:27:00 +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-11-11 11:01:49 +01:00
// TraverseRecordWithIndexPar uses transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]
func TraverseRecordWithIndexPar [ K comparable , A , B any ] ( f func ( K , A ) ReaderIOResult [ B ] ) Kleisli [ map [ K ] A , map [ K ] B ] {
2025-11-06 09:27:00 +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 ,
)
}
2025-11-11 11:01:49 +01:00
// MonadTraverseRecordPar uses transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]
func MonadTraverseRecordPar [ K comparable , A , B any ] ( as map [ K ] A , f Kleisli [ A , B ] ) ReaderIOResult [ map [ K ] B ] {
2025-11-11 15:24:45 +01:00
return record . MonadTraverse (
2025-11-06 09:27:00 +01:00
Of [ map [ K ] B ] ,
Map [ map [ K ] B , func ( B ) map [ K ] B ] ,
ApPar [ map [ K ] B , B ] ,
as ,
f ,
)
}
2025-11-11 11:01:49 +01:00
// SequenceRecordPar converts a homogeneous map of ReaderIOResult into a ReaderIOResult of map.
2025-11-06 09:27:00 +01:00
// This explicitly uses parallel execution.
//
// Parameters:
2025-11-11 11:01:49 +01:00
// - ma: Map of ReaderIOResult values
2025-11-06 09:27:00 +01:00
//
2025-11-11 11:01:49 +01:00
// Returns a ReaderIOResult containing a map of values.
func SequenceRecordPar [ K comparable , A any ] ( ma map [ K ] ReaderIOResult [ A ] ) ReaderIOResult [ map [ K ] A ] {
return MonadTraverseRecordPar ( ma , function . Identity [ ReaderIOResult [ A ] ] )
2025-11-06 09:27:00 +01:00
}