1
0
mirror of https://github.com/IBM/fp-go.git synced 2025-11-23 22:14:53 +02:00
Files
fp-go/v2/readeroption/array.go

89 lines
3.4 KiB
Go
Raw Normal View History

// 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.
package readeroption
import (
G "github.com/IBM/fp-go/v2/readeroption/generic"
)
// TraverseArray transforms an array by applying a function that returns a ReaderOption to each element.
// If any element results in None, the entire result is None.
// Otherwise, returns Some containing an array of all the unwrapped values.
//
// This is useful for performing a sequence of operations that may fail on each element of an array,
// where you want all operations to succeed or the entire computation to fail.
//
// Example:
//
// type DB struct { ... }
//
// findUser := func(id int) readeroption.ReaderOption[DB, User] { ... }
//
// userIDs := []int{1, 2, 3}
// result := F.Pipe1(
// readeroption.Of[DB](userIDs),
// readeroption.Chain(readeroption.TraverseArray[DB](findUser)),
// )
// // result will be Some([]User) if all users are found, None otherwise
func TraverseArray[E, A, B any](f func(A) ReaderOption[E, B]) Kleisli[E, []A, []B] {
return G.TraverseArray[ReaderOption[E, B], ReaderOption[E, []B], []A](f)
}
// TraverseArrayWithIndex is like TraverseArray but the function also receives the index of each element.
//
// Example:
//
// type DB struct { ... }
//
// processWithIndex := func(idx int, value string) readeroption.ReaderOption[DB, Result] {
// // Use idx in processing
// return readeroption.Asks(func(db DB) option.Option[Result] { ... })
// }
//
// values := []string{"a", "b", "c"}
// result := readeroption.TraverseArrayWithIndex[DB](processWithIndex)(values)
func TraverseArrayWithIndex[E, A, B any](f func(int, A) ReaderOption[E, B]) func([]A) ReaderOption[E, []B] {
return G.TraverseArrayWithIndex[ReaderOption[E, B], ReaderOption[E, []B], []A](f)
}
// SequenceArray converts an array of ReaderOption values into a ReaderOption of an array.
// If any element is None, the entire result is None.
// Otherwise, returns Some containing an array of all the unwrapped values.
//
// This is useful when you have multiple independent ReaderOption computations and want to
// combine their results into a single array.
//
// Example:
//
// type Config struct { ... }
//
// user1 := readeroption.Of[Config](User{ID: 1, Name: "Alice"})
// user2 := readeroption.Of[Config](User{ID: 2, Name: "Bob"})
// user3 := readeroption.None[Config, User]()
//
// result := readeroption.SequenceArray([]readeroption.ReaderOption[Config, User]{
// user1, user2, user3,
// })
// // result(config) will be option.None[[]User]() because user3 is None
//
// result2 := readeroption.SequenceArray([]readeroption.ReaderOption[Config, User]{
// user1, user2,
// })
// // result2(config) will be option.Some([]User{{ID: 1, Name: "Alice"}, {ID: 2, Name: "Bob"}})
func SequenceArray[E, A any](ma []ReaderOption[E, A]) ReaderOption[E, []A] {
return G.SequenceArray[ReaderOption[E, A], ReaderOption[E, []A]](ma)
}