mirror of
https://github.com/IBM/fp-go.git
synced 2025-11-27 22:28:29 +02:00
77 lines
2.2 KiB
Go
77 lines
2.2 KiB
Go
// Copyright (c) 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 option
|
|
|
|
import (
|
|
INTI "github.com/IBM/fp-go/v2/internal/iter"
|
|
)
|
|
|
|
// TraverseIter transforms a sequence by applying a function that returns an Option to each element.
|
|
// Returns Some containing a sequence of results if all operations succeed, None if any fails.
|
|
// This function is useful for processing sequences where each element may fail validation or transformation.
|
|
//
|
|
// The traversal short-circuits on the first None encountered, making it efficient for validation pipelines.
|
|
// The resulting sequence is lazy and will only be evaluated when iterated.
|
|
//
|
|
// Example:
|
|
//
|
|
// // Parse a sequence of strings to integers
|
|
// parse := func(s string) Option[int] {
|
|
// n, err := strconv.Atoi(s)
|
|
// if err != nil { return None[int]() }
|
|
// return Some(n)
|
|
// }
|
|
//
|
|
// // Create a sequence of strings
|
|
// strings := func(yield func(string) bool) {
|
|
// for _, s := range []string{"1", "2", "3"} {
|
|
// if !yield(s) { return }
|
|
// }
|
|
// }
|
|
//
|
|
// result := TraverseIter(parse)(strings)
|
|
// // result is Some(sequence of [1, 2, 3])
|
|
//
|
|
// // With invalid input
|
|
// invalidStrings := func(yield func(string) bool) {
|
|
// for _, s := range []string{"1", "invalid", "3"} {
|
|
// if !yield(s) { return }
|
|
// }
|
|
// }
|
|
//
|
|
// result := TraverseIter(parse)(invalidStrings)
|
|
// // result is None because "invalid" cannot be parsed
|
|
func TraverseIter[A, B any](f Kleisli[A, B]) Kleisli[Seq[A], Seq[B]] {
|
|
|
|
return INTI.Traverse[Seq[A]](
|
|
Map[B],
|
|
|
|
Of[Seq[B]],
|
|
Map[Seq[B]],
|
|
MonadAp[Seq[B]],
|
|
|
|
f,
|
|
)
|
|
}
|
|
|
|
func SequenceIter[A any](as Seq[Option[A]]) Option[Seq[A]] {
|
|
return INTI.MonadSequence(
|
|
Map(INTI.Of[Seq[A]]),
|
|
ApplicativeMonoid(INTI.Monoid[Seq[A]]()),
|
|
as,
|
|
)
|
|
}
|