Documentation
¶
Overview ¶
Package io provides the IO monad, representing synchronous computations that cannot fail.
IO is a lazy computation that encapsulates side effects and ensures referential transparency. Unlike functions that execute immediately, IO values describe computations that will be executed when explicitly invoked.
Fantasy Land Specification ¶
This implementation corresponds to the Fantasy Land IO type: https://github.com/fantasyland/fantasy-land
Implemented Fantasy Land algebras:
- Functor: https://github.com/fantasyland/fantasy-land#functor
- Apply: https://github.com/fantasyland/fantasy-land#apply
- Applicative: https://github.com/fantasyland/fantasy-land#applicative
- Chain: https://github.com/fantasyland/fantasy-land#chain
- Monad: https://github.com/fantasyland/fantasy-land#monad
Core Concepts ¶
The IO type is defined as a function that takes no arguments and returns a value:
type IO[A any] = func() A
This simple definition provides powerful guarantees:
- Lazy evaluation: computations are not executed until explicitly called
- Composability: IO operations can be combined without executing them
- Referential transparency: IO values can be safely reused and passed around
Basic Usage ¶
// Creating IO values
greeting := io.Of("Hello, World!")
timestamp := io.Now
// Transforming values with Map
upper := io.Map(strings.ToUpper)(greeting)
// Chaining computations with Chain
result := io.Chain(func(s string) io.IO[int] {
return io.Of(len(s))
})(greeting)
// Executing the computation
value := result() // Only now does the computation run
Monadic Operations ¶
IO implements the Monad interface, providing:
- Of: Wrap a pure value in IO
- Map: Transform the result of a computation
- Chain (FlatMap): Sequence computations that return IO
- Ap: Apply a function wrapped in IO to a value wrapped in IO
Parallel vs Sequential Execution ¶
IO supports both parallel and sequential execution of applicative operations:
- Ap/MonadAp: Parallel execution (default)
- ApSeq/MonadApSeq: Sequential execution
- ApPar/MonadApPar: Explicit parallel execution
Time-based Operations ¶
// Delay execution delayed := io.Delay(time.Second)(computation) // Execute after a specific time scheduled := io.After(timestamp)(computation) // Measure execution time withDuration := io.WithDuration(computation) withTime := io.WithTime(computation)
Resource Management ¶
IO provides utilities for safe resource management:
// Bracket ensures cleanup
result := io.Bracket(
acquire,
use,
release,
)
// WithResource simplifies resource patterns
withFile := io.WithResource(openFile, closeFile)
result := withFile(func(f *os.File) io.IO[Data] {
return readData(f)
})
Retry Logic ¶
// Retry with exponential backoff
result := io.Retrying(
retry.ExponentialBackoff(time.Second, 5),
func(status retry.RetryStatus) io.IO[Result] {
return fetchData()
},
func(r Result) bool { return r.ShouldRetry },
)
Traversal Operations ¶
IO provides utilities for working with collections:
- TraverseArray: Apply IO-returning function to array elements
- TraverseRecord: Apply IO-returning function to map values
- SequenceArray: Convert []IO[A] to IO[[]A]
- SequenceRecord: Convert map[K]IO[A] to IO[map[K]A]
Both parallel and sequential variants are available (e.g., TraverseArraySeq).
Do Notation ¶
IO supports do-notation style composition for imperative-looking code:
result := pipe.Pipe3(
io.Do(State{}),
io.Bind("user", func(s State) io.IO[User] {
return fetchUser(s.userId)
}),
io.Bind("posts", func(s State) io.IO[[]Post] {
return fetchPosts(s.user.Id)
}),
io.Map(func(s State) Result {
return formatResult(s.user, s.posts)
}),
)
Logging and Debugging ¶
// Log values during computation
logged := io.ChainFirst(io.Logger()("Fetched user"))(fetchUser)
// Printf-style logging
logged := io.ChainFirst(io.Printf("User: %+v"))(fetchUser)
Subpackages ¶
- io/file: File system operations returning IO
- io/generic: Generic IO utilities and type classes
- io/testing: Testing utilities for IO laws
Relationship to Other Monads ¶
IO is the simplest effect monad in the fp-go library:
- IOEither: IO that can fail (combines IO with Either)
- IOOption: IO that may not return a value (combines IO with Option)
- ReaderIO: IO with dependency injection (combines Reader with IO)
- ReaderIOEither: Full effect system with DI and error handling
Index ¶
- func Eq[A any](e EQ.Eq[A]) EQ.Eq[IO[A]]
- func FromStrictEquals[A comparable]() EQ.Eq[IO[A]]
- func Logger[A any](loggers ...*log.Logger) func(string) Kleisli[A, A]
- func TraverseParTuple10[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) ...
- func TraverseParTuple2[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], T1, T2, A1, A2 any](f1 F1, f2 F2) func(tuple.Tuple2[A1, A2]) IO[tuple.Tuple2[T1, T2]]
- func TraverseParTuple3[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3) func(tuple.Tuple3[A1, A2, A3]) IO[tuple.Tuple3[T1, T2, T3]]
- func TraverseParTuple4[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4) func(tuple.Tuple4[A1, A2, A3, A4]) IO[tuple.Tuple4[T1, T2, T3, T4]]
- func TraverseParTuple5[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) func(tuple.Tuple5[A1, A2, A3, A4, A5]) IO[tuple.Tuple5[T1, T2, T3, T4, T5]]
- func TraverseParTuple6[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) ...
- func TraverseParTuple7[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) ...
- func TraverseParTuple8[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) ...
- func TraverseParTuple9[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) ...
- func TraverseSeqTuple10[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) ...
- func TraverseSeqTuple2[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], T1, T2, A1, A2 any](f1 F1, f2 F2) func(tuple.Tuple2[A1, A2]) IO[tuple.Tuple2[T1, T2]]
- func TraverseSeqTuple3[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3) func(tuple.Tuple3[A1, A2, A3]) IO[tuple.Tuple3[T1, T2, T3]]
- func TraverseSeqTuple4[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4) func(tuple.Tuple4[A1, A2, A3, A4]) IO[tuple.Tuple4[T1, T2, T3, T4]]
- func TraverseSeqTuple5[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) func(tuple.Tuple5[A1, A2, A3, A4, A5]) IO[tuple.Tuple5[T1, T2, T3, T4, T5]]
- func TraverseSeqTuple6[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) ...
- func TraverseSeqTuple7[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) ...
- func TraverseSeqTuple8[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) ...
- func TraverseSeqTuple9[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) ...
- func TraverseTuple10[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) ...
- func TraverseTuple2[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], T1, T2, A1, A2 any](f1 F1, f2 F2) func(tuple.Tuple2[A1, A2]) IO[tuple.Tuple2[T1, T2]]
- func TraverseTuple3[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3) func(tuple.Tuple3[A1, A2, A3]) IO[tuple.Tuple3[T1, T2, T3]]
- func TraverseTuple4[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4) func(tuple.Tuple4[A1, A2, A3, A4]) IO[tuple.Tuple4[T1, T2, T3, T4]]
- func TraverseTuple5[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) func(tuple.Tuple5[A1, A2, A3, A4, A5]) IO[tuple.Tuple5[T1, T2, T3, T4, T5]]
- func TraverseTuple6[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) ...
- func TraverseTuple7[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) ...
- func TraverseTuple8[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) ...
- func TraverseTuple9[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) ...
- func WithLock[A any](lock IO[context.CancelFunc]) func(fa IO[A]) IO[A]
- type Consumer
- type IO
- func Bracket[A, B, ANY any](acquire IO[A], use Kleisli[A, B], release func(A, B) IO[ANY]) IO[B]
- func Defer[A any](gen func() IO[A]) IO[A]
- func Do[S any](empty S) IO[S]
- func Flatten[A any](mma IO[IO[A]]) IO[A]
- func FromIO[A any](a IO[A]) IO[A]
- func FromImpure[ANY ~func()](f ANY) IO[any]
- func Memoize[A any](ma IO[A]) IO[A]
- func MonadAp[A, B any](mab IO[func(A) B], ma IO[A]) IO[B]
- func MonadApFirst[A, B any](first IO[A], second IO[B]) IO[A]
- func MonadApPar[A, B any](mab IO[func(A) B], ma IO[A]) IO[B]
- func MonadApSecond[A, B any](first IO[A], second IO[B]) IO[B]
- func MonadApSeq[A, B any](mab IO[func(A) B], ma IO[A]) IO[B]
- func MonadChain[A, B any](fa IO[A], f Kleisli[A, B]) IO[B]
- func MonadChainFirst[A, B any](fa IO[A], f Kleisli[A, B]) IO[A]
- func MonadChainTo[A, B any](fa IO[A], fb IO[B]) IO[B]
- func MonadFlap[B, A any](fab IO[func(A) B], a A) IO[B]
- func MonadMap[A, B any](fa IO[A], f func(A) B) IO[B]
- func MonadMapTo[A, B any](fa IO[A], b B) IO[B]
- func MonadOf[A any](a A) IO[A]
- func MonadTraverseArray[A, B any](tas []A, f Kleisli[A, B]) IO[[]B]
- func MonadTraverseArraySeq[A, B any](tas []A, f Kleisli[A, B]) IO[[]B]
- func MonadTraverseRecord[K comparable, A, B any](tas map[K]A, f Kleisli[A, B]) IO[map[K]B]
- func MonadTraverseRecordSeq[K comparable, A, B any](tas map[K]A, f Kleisli[A, B]) IO[map[K]B]
- func Of[A any](a A) IO[A]
- func Retrying[A any](policy R.RetryPolicy, action Kleisli[R.RetryStatus, A], check func(A) bool) IO[A]
- func SequenceArray[A any](tas []IO[A]) IO[[]A]
- func SequenceArraySeq[A any](tas []IO[A]) IO[[]A]
- func SequenceParT1[T1 any](t1 IO[T1]) IO[tuple.Tuple1[T1]]
- func SequenceParT10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], ...) IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
- func SequenceParT2[T1, T2 any](t1 IO[T1], t2 IO[T2]) IO[tuple.Tuple2[T1, T2]]
- func SequenceParT3[T1, T2, T3 any](t1 IO[T1], t2 IO[T2], t3 IO[T3]) IO[tuple.Tuple3[T1, T2, T3]]
- func SequenceParT4[T1, T2, T3, T4 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4]) IO[tuple.Tuple4[T1, T2, T3, T4]]
- func SequenceParT5[T1, T2, T3, T4, T5 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5]) IO[tuple.Tuple5[T1, T2, T3, T4, T5]]
- func SequenceParT6[T1, T2, T3, T4, T5, T6 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6]) IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
- func SequenceParT7[T1, T2, T3, T4, T5, T6, T7 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7]) IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
- func SequenceParT8[T1, T2, T3, T4, T5, T6, T7, T8 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], ...) IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
- func SequenceParT9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], ...) IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
- func SequenceParTuple1[T1 any](t tuple.Tuple1[IO[T1]]) IO[tuple.Tuple1[T1]]
- func SequenceParTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](...) IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
- func SequenceParTuple2[T1, T2 any](t tuple.Tuple2[IO[T1], IO[T2]]) IO[tuple.Tuple2[T1, T2]]
- func SequenceParTuple3[T1, T2, T3 any](t tuple.Tuple3[IO[T1], IO[T2], IO[T3]]) IO[tuple.Tuple3[T1, T2, T3]]
- func SequenceParTuple4[T1, T2, T3, T4 any](t tuple.Tuple4[IO[T1], IO[T2], IO[T3], IO[T4]]) IO[tuple.Tuple4[T1, T2, T3, T4]]
- func SequenceParTuple5[T1, T2, T3, T4, T5 any](t tuple.Tuple5[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5]]) IO[tuple.Tuple5[T1, T2, T3, T4, T5]]
- func SequenceParTuple6[T1, T2, T3, T4, T5, T6 any](t tuple.Tuple6[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6]]) IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
- func SequenceParTuple7[T1, T2, T3, T4, T5, T6, T7 any](t tuple.Tuple7[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6], IO[T7]]) IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
- func SequenceParTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](t tuple.Tuple8[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6], IO[T7], IO[T8]]) IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
- func SequenceParTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](...) IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
- func SequenceRecord[K comparable, A any](tas map[K]IO[A]) IO[map[K]A]
- func SequenceRecordSeq[K comparable, A any](tas map[K]IO[A]) IO[map[K]A]
- func SequenceSeqT1[T1 any](t1 IO[T1]) IO[tuple.Tuple1[T1]]
- func SequenceSeqT10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], ...) IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
- func SequenceSeqT2[T1, T2 any](t1 IO[T1], t2 IO[T2]) IO[tuple.Tuple2[T1, T2]]
- func SequenceSeqT3[T1, T2, T3 any](t1 IO[T1], t2 IO[T2], t3 IO[T3]) IO[tuple.Tuple3[T1, T2, T3]]
- func SequenceSeqT4[T1, T2, T3, T4 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4]) IO[tuple.Tuple4[T1, T2, T3, T4]]
- func SequenceSeqT5[T1, T2, T3, T4, T5 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5]) IO[tuple.Tuple5[T1, T2, T3, T4, T5]]
- func SequenceSeqT6[T1, T2, T3, T4, T5, T6 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6]) IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
- func SequenceSeqT7[T1, T2, T3, T4, T5, T6, T7 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7]) IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
- func SequenceSeqT8[T1, T2, T3, T4, T5, T6, T7, T8 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], ...) IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
- func SequenceSeqT9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], ...) IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
- func SequenceSeqTuple1[T1 any](t tuple.Tuple1[IO[T1]]) IO[tuple.Tuple1[T1]]
- func SequenceSeqTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](...) IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
- func SequenceSeqTuple2[T1, T2 any](t tuple.Tuple2[IO[T1], IO[T2]]) IO[tuple.Tuple2[T1, T2]]
- func SequenceSeqTuple3[T1, T2, T3 any](t tuple.Tuple3[IO[T1], IO[T2], IO[T3]]) IO[tuple.Tuple3[T1, T2, T3]]
- func SequenceSeqTuple4[T1, T2, T3, T4 any](t tuple.Tuple4[IO[T1], IO[T2], IO[T3], IO[T4]]) IO[tuple.Tuple4[T1, T2, T3, T4]]
- func SequenceSeqTuple5[T1, T2, T3, T4, T5 any](t tuple.Tuple5[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5]]) IO[tuple.Tuple5[T1, T2, T3, T4, T5]]
- func SequenceSeqTuple6[T1, T2, T3, T4, T5, T6 any](t tuple.Tuple6[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6]]) IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
- func SequenceSeqTuple7[T1, T2, T3, T4, T5, T6, T7 any](t tuple.Tuple7[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6], IO[T7]]) IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
- func SequenceSeqTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](t tuple.Tuple8[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6], IO[T7], IO[T8]]) IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
- func SequenceSeqTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](...) IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
- func SequenceT1[T1 any](t1 IO[T1]) IO[tuple.Tuple1[T1]]
- func SequenceT10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], ...) IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
- func SequenceT2[T1, T2 any](t1 IO[T1], t2 IO[T2]) IO[tuple.Tuple2[T1, T2]]
- func SequenceT3[T1, T2, T3 any](t1 IO[T1], t2 IO[T2], t3 IO[T3]) IO[tuple.Tuple3[T1, T2, T3]]
- func SequenceT4[T1, T2, T3, T4 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4]) IO[tuple.Tuple4[T1, T2, T3, T4]]
- func SequenceT5[T1, T2, T3, T4, T5 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5]) IO[tuple.Tuple5[T1, T2, T3, T4, T5]]
- func SequenceT6[T1, T2, T3, T4, T5, T6 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6]) IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
- func SequenceT7[T1, T2, T3, T4, T5, T6, T7 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7]) IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
- func SequenceT8[T1, T2, T3, T4, T5, T6, T7, T8 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], ...) IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
- func SequenceT9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], ...) IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
- func SequenceTuple1[T1 any](t tuple.Tuple1[IO[T1]]) IO[tuple.Tuple1[T1]]
- func SequenceTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](...) IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
- func SequenceTuple2[T1, T2 any](t tuple.Tuple2[IO[T1], IO[T2]]) IO[tuple.Tuple2[T1, T2]]
- func SequenceTuple3[T1, T2, T3 any](t tuple.Tuple3[IO[T1], IO[T2], IO[T3]]) IO[tuple.Tuple3[T1, T2, T3]]
- func SequenceTuple4[T1, T2, T3, T4 any](t tuple.Tuple4[IO[T1], IO[T2], IO[T3], IO[T4]]) IO[tuple.Tuple4[T1, T2, T3, T4]]
- func SequenceTuple5[T1, T2, T3, T4, T5 any](t tuple.Tuple5[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5]]) IO[tuple.Tuple5[T1, T2, T3, T4, T5]]
- func SequenceTuple6[T1, T2, T3, T4, T5, T6 any](t tuple.Tuple6[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6]]) IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
- func SequenceTuple7[T1, T2, T3, T4, T5, T6, T7 any](t tuple.Tuple7[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6], IO[T7]]) IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
- func SequenceTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](t tuple.Tuple8[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6], IO[T7], IO[T8]]) IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
- func SequenceTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](...) IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
- func WithDuration[A any](a IO[A]) IO[Pair[time.Duration, A]]
- func WithTime[A any](a IO[A]) IO[Pair[Pair[time.Time, time.Time], A]]
- type IOApplicative
- type IOFunctor
- type IOMonad
- type IOPointed
- type Kleisli
- func FromConsumerK[A any](c Consumer[A]) Kleisli[A, struct{}]
- func LogGo[A any](prefix string) Kleisli[A, A]
- func Logf[A any](prefix string) Kleisli[A, A]
- func PrintGo[A any](prefix string) Kleisli[A, A]
- func Printf[A any](prefix string) Kleisli[A, A]
- func TraverseArray[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B]
- func TraverseArraySeq[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B]
- func TraverseArrayWithIndex[A, B any](f func(int, A) IO[B]) Kleisli[[]A, []B]
- func TraverseArrayWithIndexSeq[A, B any](f func(int, A) IO[B]) Kleisli[[]A, []B]
- func TraverseIter[A, B any](f Kleisli[A, B]) Kleisli[Seq[A], Seq[B]]
- func TraverseParTuple1[F1 ~Kleisli[A1, T1], T1, A1 any](f1 F1) Kleisli[tuple.Tuple1[A1], tuple.Tuple1[T1]]
- func TraverseRecord[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B]
- func TraverseRecordSeq[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B]
- func TraverseRecordWithIndeSeq[K comparable, A, B any](f func(K, A) IO[B]) Kleisli[map[K]A, map[K]B]
- func TraverseRecordWithIndex[K comparable, A, B any](f func(K, A) IO[B]) Kleisli[map[K]A, map[K]B]
- func TraverseSeqTuple1[F1 ~Kleisli[A1, T1], T1, A1 any](f1 F1) Kleisli[tuple.Tuple1[A1], tuple.Tuple1[T1]]
- func TraverseTuple1[F1 ~Kleisli[A1, T1], T1, A1 any](f1 F1) Kleisli[tuple.Tuple1[A1], tuple.Tuple1[T1]]
- func WithResource[R, A, ANY any](onCreate IO[R], onRelease func(R) IO[ANY]) Kleisli[Kleisli[R, A], A]
- type Monoid
- type Operator
- func After[A any](timestamp time.Time) Operator[A, A]
- func Ap[B, A any](ma IO[A]) Operator[func(A) B, B]
- func ApFirst[A, B any](second IO[B]) Operator[A, A]
- func ApPar[B, A any](ma IO[A]) Operator[func(A) B, B]
- func ApS[S1, S2, T any](setter func(T) func(S1) S2, fa IO[T]) Operator[S1, S2]
- func ApSL[S, T any](lens L.Lens[S, T], fa IO[T]) Operator[S, S]
- func ApSecond[A, B any](second IO[B]) Operator[A, B]
- func ApSeq[B, A any](ma IO[A]) Operator[func(A) B, B]
- func Bind[S1, S2, T any](setter func(T) func(S1) S2, f Kleisli[S1, T]) Operator[S1, S2]
- func BindL[S, T any](lens L.Lens[S, T], f Kleisli[T, T]) Operator[S, S]
- func BindTo[S1, T any](setter func(T) S1) Operator[T, S1]
- func Chain[A, B any](f Kleisli[A, B]) Operator[A, B]
- func ChainConsumer[A any](c Consumer[A]) Operator[A, struct{}]
- func ChainFirst[A, B any](f Kleisli[A, B]) Operator[A, A]
- func ChainTo[A, B any](fb IO[B]) Operator[A, B]
- func Delay[A any](delay time.Duration) Operator[A, A]
- func Flap[B, A any](a A) Operator[func(A) B, B]
- func Let[S1, S2, T any](setter func(T) func(S1) S2, f func(S1) T) Operator[S1, S2]
- func LetL[S, T any](lens L.Lens[S, T], f func(T) T) Operator[S, S]
- func LetTo[S1, S2, T any](setter func(T) func(S1) S2, b T) Operator[S1, S2]
- func LetToL[S, T any](lens L.Lens[S, T], b T) Operator[S, S]
- func Map[A, B any](f func(A) B) Operator[A, B]
- func MapTo[A, B any](b B) Operator[A, B]
- type Pair
- type RetryStatus
- type Semigroup
- type Seq
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Eq ¶
Eq implements the equals predicate for values contained in the IO monad. It lifts an Eq[A] into an Eq[IO[A]] by executing both IO computations and comparing their results.
Example:
intEq := eq.FromStrictEquals[int]() ioEq := io.Eq(intEq) result := ioEq.Equals(io.Of(42), io.Of(42)) // true
func FromStrictEquals ¶
func FromStrictEquals[A comparable]() EQ.Eq[IO[A]]
FromStrictEquals constructs an Eq[IO[A]] from the canonical comparison function for comparable types. This is a convenience function that combines Eq with the standard equality operator.
Example:
ioEq := io.FromStrictEquals[int]() result := ioEq.Equals(io.Of(42), io.Of(42)) // true
func Logger ¶
Logger constructs a logger function that can be used with ChainFirst or similar operations. It logs values using the provided loggers (or the default logger if none provided).
Example:
result := pipe.Pipe2(
fetchUser(),
io.ChainFirst(io.Logger[User]()("Fetched user")),
processUser,
)
func TraverseParTuple10 ¶
func TraverseParTuple10[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], F7 ~Kleisli[A7, T7], F8 ~Kleisli[A8, T8], F9 ~Kleisli[A9, T9], F10 ~Kleisli[A10, T10], T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) func(tuple.Tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]) IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
TraverseParTuple10 converts a [tuple.Tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]] into a [IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func TraverseParTuple2 ¶
func TraverseParTuple2[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], T1, T2, A1, A2 any](f1 F1, f2 F2) func(tuple.Tuple2[A1, A2]) IO[tuple.Tuple2[T1, T2]]
TraverseParTuple2 converts a [tuple.Tuple2[A1, A2]] into a [IO[tuple.Tuple2[T1, T2]]]
func TraverseParTuple3 ¶
func TraverseParTuple3[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], T1, T2, T3, A1, A2, A3 any](f1 F1, f2 F2, f3 F3) func(tuple.Tuple3[A1, A2, A3]) IO[tuple.Tuple3[T1, T2, T3]]
TraverseParTuple3 converts a [tuple.Tuple3[A1, A2, A3]] into a [IO[tuple.Tuple3[T1, T2, T3]]]
func TraverseParTuple4 ¶
func TraverseParTuple4[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], T1, T2, T3, T4, A1, A2, A3, A4 any](f1 F1, f2 F2, f3 F3, f4 F4) func(tuple.Tuple4[A1, A2, A3, A4]) IO[tuple.Tuple4[T1, T2, T3, T4]]
TraverseParTuple4 converts a [tuple.Tuple4[A1, A2, A3, A4]] into a [IO[tuple.Tuple4[T1, T2, T3, T4]]]
func TraverseParTuple5 ¶
func TraverseParTuple5[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], T1, T2, T3, T4, T5, A1, A2, A3, A4, A5 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) func(tuple.Tuple5[A1, A2, A3, A4, A5]) IO[tuple.Tuple5[T1, T2, T3, T4, T5]]
TraverseParTuple5 converts a [tuple.Tuple5[A1, A2, A3, A4, A5]] into a [IO[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func TraverseParTuple6 ¶
func TraverseParTuple6[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], T1, T2, T3, T4, T5, T6, A1, A2, A3, A4, A5, A6 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) func(tuple.Tuple6[A1, A2, A3, A4, A5, A6]) IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
TraverseParTuple6 converts a [tuple.Tuple6[A1, A2, A3, A4, A5, A6]] into a [IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func TraverseParTuple7 ¶
func TraverseParTuple7[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], F7 ~Kleisli[A7, T7], T1, T2, T3, T4, T5, T6, T7, A1, A2, A3, A4, A5, A6, A7 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) func(tuple.Tuple7[A1, A2, A3, A4, A5, A6, A7]) IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
TraverseParTuple7 converts a [tuple.Tuple7[A1, A2, A3, A4, A5, A6, A7]] into a [IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func TraverseParTuple8 ¶
func TraverseParTuple8[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], F7 ~Kleisli[A7, T7], F8 ~Kleisli[A8, T8], T1, T2, T3, T4, T5, T6, T7, T8, A1, A2, A3, A4, A5, A6, A7, A8 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) func(tuple.Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]) IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
TraverseParTuple8 converts a [tuple.Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]] into a [IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func TraverseParTuple9 ¶
func TraverseParTuple9[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], F7 ~Kleisli[A7, T7], F8 ~Kleisli[A8, T8], F9 ~Kleisli[A9, T9], T1, T2, T3, T4, T5, T6, T7, T8, T9, A1, A2, A3, A4, A5, A6, A7, A8, A9 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) func(tuple.Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]) IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
TraverseParTuple9 converts a [tuple.Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]] into a [IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func TraverseSeqTuple10 ¶
func TraverseSeqTuple10[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], F7 ~Kleisli[A7, T7], F8 ~Kleisli[A8, T8], F9 ~Kleisli[A9, T9], F10 ~Kleisli[A10, T10], T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) func(tuple.Tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]) IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
TraverseSeqTuple10 converts a [tuple.Tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]] into a [IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func TraverseSeqTuple2 ¶
func TraverseSeqTuple2[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], T1, T2, A1, A2 any](f1 F1, f2 F2) func(tuple.Tuple2[A1, A2]) IO[tuple.Tuple2[T1, T2]]
TraverseSeqTuple2 converts a [tuple.Tuple2[A1, A2]] into a [IO[tuple.Tuple2[T1, T2]]]
func TraverseSeqTuple3 ¶
func TraverseSeqTuple3[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], T1, T2, T3, A1, A2, A3 any](f1 F1, f2 F2, f3 F3) func(tuple.Tuple3[A1, A2, A3]) IO[tuple.Tuple3[T1, T2, T3]]
TraverseSeqTuple3 converts a [tuple.Tuple3[A1, A2, A3]] into a [IO[tuple.Tuple3[T1, T2, T3]]]
func TraverseSeqTuple4 ¶
func TraverseSeqTuple4[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], T1, T2, T3, T4, A1, A2, A3, A4 any](f1 F1, f2 F2, f3 F3, f4 F4) func(tuple.Tuple4[A1, A2, A3, A4]) IO[tuple.Tuple4[T1, T2, T3, T4]]
TraverseSeqTuple4 converts a [tuple.Tuple4[A1, A2, A3, A4]] into a [IO[tuple.Tuple4[T1, T2, T3, T4]]]
func TraverseSeqTuple5 ¶
func TraverseSeqTuple5[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], T1, T2, T3, T4, T5, A1, A2, A3, A4, A5 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) func(tuple.Tuple5[A1, A2, A3, A4, A5]) IO[tuple.Tuple5[T1, T2, T3, T4, T5]]
TraverseSeqTuple5 converts a [tuple.Tuple5[A1, A2, A3, A4, A5]] into a [IO[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func TraverseSeqTuple6 ¶
func TraverseSeqTuple6[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], T1, T2, T3, T4, T5, T6, A1, A2, A3, A4, A5, A6 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) func(tuple.Tuple6[A1, A2, A3, A4, A5, A6]) IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
TraverseSeqTuple6 converts a [tuple.Tuple6[A1, A2, A3, A4, A5, A6]] into a [IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func TraverseSeqTuple7 ¶
func TraverseSeqTuple7[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], F7 ~Kleisli[A7, T7], T1, T2, T3, T4, T5, T6, T7, A1, A2, A3, A4, A5, A6, A7 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) func(tuple.Tuple7[A1, A2, A3, A4, A5, A6, A7]) IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
TraverseSeqTuple7 converts a [tuple.Tuple7[A1, A2, A3, A4, A5, A6, A7]] into a [IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func TraverseSeqTuple8 ¶
func TraverseSeqTuple8[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], F7 ~Kleisli[A7, T7], F8 ~Kleisli[A8, T8], T1, T2, T3, T4, T5, T6, T7, T8, A1, A2, A3, A4, A5, A6, A7, A8 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) func(tuple.Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]) IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
TraverseSeqTuple8 converts a [tuple.Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]] into a [IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func TraverseSeqTuple9 ¶
func TraverseSeqTuple9[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], F7 ~Kleisli[A7, T7], F8 ~Kleisli[A8, T8], F9 ~Kleisli[A9, T9], T1, T2, T3, T4, T5, T6, T7, T8, T9, A1, A2, A3, A4, A5, A6, A7, A8, A9 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) func(tuple.Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]) IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
TraverseSeqTuple9 converts a [tuple.Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]] into a [IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func TraverseTuple10 ¶
func TraverseTuple10[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], F7 ~Kleisli[A7, T7], F8 ~Kleisli[A8, T8], F9 ~Kleisli[A9, T9], F10 ~Kleisli[A10, T10], T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) func(tuple.Tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]) IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
TraverseTuple10 converts a [tuple.Tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]] into a [IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func TraverseTuple2 ¶
func TraverseTuple2[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], T1, T2, A1, A2 any](f1 F1, f2 F2) func(tuple.Tuple2[A1, A2]) IO[tuple.Tuple2[T1, T2]]
TraverseTuple2 converts a [tuple.Tuple2[A1, A2]] into a [IO[tuple.Tuple2[T1, T2]]]
func TraverseTuple3 ¶
func TraverseTuple3[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], T1, T2, T3, A1, A2, A3 any](f1 F1, f2 F2, f3 F3) func(tuple.Tuple3[A1, A2, A3]) IO[tuple.Tuple3[T1, T2, T3]]
TraverseTuple3 converts a [tuple.Tuple3[A1, A2, A3]] into a [IO[tuple.Tuple3[T1, T2, T3]]]
func TraverseTuple4 ¶
func TraverseTuple4[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], T1, T2, T3, T4, A1, A2, A3, A4 any](f1 F1, f2 F2, f3 F3, f4 F4) func(tuple.Tuple4[A1, A2, A3, A4]) IO[tuple.Tuple4[T1, T2, T3, T4]]
TraverseTuple4 converts a [tuple.Tuple4[A1, A2, A3, A4]] into a [IO[tuple.Tuple4[T1, T2, T3, T4]]]
func TraverseTuple5 ¶
func TraverseTuple5[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], T1, T2, T3, T4, T5, A1, A2, A3, A4, A5 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) func(tuple.Tuple5[A1, A2, A3, A4, A5]) IO[tuple.Tuple5[T1, T2, T3, T4, T5]]
TraverseTuple5 converts a [tuple.Tuple5[A1, A2, A3, A4, A5]] into a [IO[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func TraverseTuple6 ¶
func TraverseTuple6[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], T1, T2, T3, T4, T5, T6, A1, A2, A3, A4, A5, A6 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) func(tuple.Tuple6[A1, A2, A3, A4, A5, A6]) IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
TraverseTuple6 converts a [tuple.Tuple6[A1, A2, A3, A4, A5, A6]] into a [IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func TraverseTuple7 ¶
func TraverseTuple7[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], F7 ~Kleisli[A7, T7], T1, T2, T3, T4, T5, T6, T7, A1, A2, A3, A4, A5, A6, A7 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) func(tuple.Tuple7[A1, A2, A3, A4, A5, A6, A7]) IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
TraverseTuple7 converts a [tuple.Tuple7[A1, A2, A3, A4, A5, A6, A7]] into a [IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func TraverseTuple8 ¶
func TraverseTuple8[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], F7 ~Kleisli[A7, T7], F8 ~Kleisli[A8, T8], T1, T2, T3, T4, T5, T6, T7, T8, A1, A2, A3, A4, A5, A6, A7, A8 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) func(tuple.Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]) IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
TraverseTuple8 converts a [tuple.Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]] into a [IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func TraverseTuple9 ¶
func TraverseTuple9[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], F7 ~Kleisli[A7, T7], F8 ~Kleisli[A8, T8], F9 ~Kleisli[A9, T9], T1, T2, T3, T4, T5, T6, T7, T8, T9, A1, A2, A3, A4, A5, A6, A7, A8, A9 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) func(tuple.Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]) IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
TraverseTuple9 converts a [tuple.Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]] into a [IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func WithLock ¶
WithLock executes the provided IO operation in the scope of a lock. The lock parameter should be an IO that acquires a lock and returns a function to release it.
This ensures that the operation is executed with exclusive access to a shared resource, and the lock is always released even if the operation panics.
Example:
mutex := &sync.Mutex{}
lock := io.FromImpure(func() context.CancelFunc {
mutex.Lock()
return func() { mutex.Unlock() }
})
safeOperation := io.WithLock(lock)(dangerousOperation)
result := safeOperation()
Types ¶
type IO ¶
type IO[A any] = func() A
IO represents a synchronous computation that cannot fail refer to [https://andywhite.xyz/posts/2021-01-27-rte-foundations/#ioltagt] for more details
Now is an IO computation that returns the current timestamp when executed. Each execution returns the current time at that moment.
Example:
timestamp := io.Now()
func Bracket ¶
Bracket makes sure that a resource is cleaned up in the event of an error. The release action is called regardless of whether the body action returns and error or not.
func Defer ¶
Defer creates an IO by creating a brand new IO via a generator function each time. This allows for dynamic creation of IO computations based on runtime conditions.
Example:
deferred := io.Defer(func() io.IO[int] {
if someCondition() {
return io.Of(1)
}
return io.Of(2)
})
func Do ¶
Do creates an empty context of type S to be used with the Bind operation. This is the starting point for do-notation style composition.
Example:
type State struct {
user User
posts []Post
}
result := pipe.Pipe2(
io.Do(State{}),
io.Bind("user", fetchUser),
io.Bind("posts", func(s State) io.IO[[]Post] {
return fetchPosts(s.user.Id)
}),
)
func Flatten ¶
Flatten removes one level of nesting from a nested IO computation. Converts IO[IO[A]] to IO[A].
Example:
nested := io.Of(io.Of(42)) flattened := io.Flatten(nested) result := flattened() // returns 42
func FromIO ¶
FromIO is an identity function that returns the IO value unchanged. Useful for type conversions and maintaining consistency with other monad packages.
func FromImpure ¶
FromImpure converts a side effect without a return value into a side effect that returns any
func MonadAp ¶
MonadAp implements the `ap` operation. Depending on a feature flag this will be sequential or parallel, the preferred implementation is parallel
func MonadApFirst ¶
MonadApFirst combines two effectful actions, keeping only the result of the first.
func MonadApPar ¶
MonadApPar implements the applicative on two threads, the main thread executes mab and the actuall apply operation and the second thread computes ma. Communication between the threads happens via a channel
func MonadApSecond ¶
MonadApSecond combines two effectful actions, keeping only the result of the second.
func MonadApSeq ¶
MonadApSeq implements the applicative on a single thread by first executing mab and the ma
func MonadChain ¶
MonadChain composes computations in sequence, using the return value of one computation to determine the next computation.
func MonadChainFirst ¶
MonadChainFirst composes computations in sequence, using the return value of one computation to determine the next computation and keeping only the result of the first.
func MonadChainTo ¶
MonadChainTo composes computations in sequence, ignoring the return value of the first computation
func MonadFlap ¶
MonadFlap applies a value to a function wrapped in IO. This is the reverse of Ap - instead of applying IO[func] to IO[value], it applies a pure value to IO[func].
Example:
addFive := io.Of(N.Add(5)) result := io.MonadFlap(addFive, 10) // returns IO[15]
func MonadMap ¶
MonadMap transforms the result of an IO computation by applying a function to it. The function is only applied when the IO is executed.
Example:
doubled := io.MonadMap(io.Of(21), N.Mul(2)) result := doubled() // returns 42
func MonadMapTo ¶
MonadMapTo replaces the result of an IO computation with a constant value. The original computation is still executed, but its result is discarded.
Example:
always42 := io.MonadMapTo(sideEffect, 42)
func MonadOf ¶
MonadOf wraps a pure value in an IO context. This is an alias for Of, following the monadic naming convention.
func MonadTraverseArray ¶
MonadTraverseArray applies an IO-returning function to each element of an array and collects the results into an IO of an array. Executes in parallel by default.
Example:
fetchUsers := func(id int) io.IO[User] { return fetchUser(id) }
users := io.MonadTraverseArray([]int{1, 2, 3}, fetchUsers)
result := users() // []User with all fetched users
func MonadTraverseArraySeq ¶
MonadTraverseArraySeq applies an IO-returning function to each element of an array and collects the results into an IO of an array. Executes sequentially (one after another).
Example:
fetchUsers := func(id int) io.IO[User] { return fetchUser(id) }
users := io.MonadTraverseArraySeq([]int{1, 2, 3}, fetchUsers)
func MonadTraverseRecord ¶
func MonadTraverseRecord[K comparable, A, B any](tas map[K]A, f Kleisli[A, B]) IO[map[K]B]
MonadTraverseRecord applies an IO-returning function to each value in a map and collects the results into an IO of a map. Executes in parallel by default.
Example:
fetchData := func(url string) io.IO[Data] { return fetch(url) }
urls := map[string]string{"a": "http://a.com", "b": "http://b.com"}
data := io.MonadTraverseRecord(urls, fetchData)
func MonadTraverseRecordSeq ¶
func MonadTraverseRecordSeq[K comparable, A, B any](tas map[K]A, f Kleisli[A, B]) IO[map[K]B]
MonadTraverseRecordSeq applies an IO-returning function to each value in a map and collects the results into an IO of a map. Executes sequentially.
func Of ¶
Of wraps a pure value in an IO context, creating a computation that returns that value. This is the monadic return operation for IO.
Example:
greeting := io.Of("Hello, World!")
result := greeting() // returns "Hello, World!"
func Retrying ¶
func Retrying[A any]( policy R.RetryPolicy, action Kleisli[R.RetryStatus, A], check func(A) bool, ) IO[A]
Retrying retries an IO action according to a retry policy until it succeeds or the policy gives up.
Parameters:
- policy: The retry policy that determines delays and maximum attempts
- action: A function that takes retry status and returns an IO computation
- check: A predicate that determines if the result should trigger a retry (true = retry)
The action receives retry status information (attempt number, cumulative delay, etc.) which can be used for logging or conditional behavior.
Example:
result := io.Retrying(
retry.ExponentialBackoff(time.Second, 5),
func(status retry.RetryStatus) io.IO[Response] {
log.Printf("Attempt %d", status.IterNumber)
return fetchData()
},
func(r Response) bool { return r.StatusCode >= 500 },
)
func SequenceArray ¶
SequenceArray converts an array of IO computations into an IO of an array of results. All computations are executed in parallel by default.
Example:
operations := []io.IO[int]{fetchA(), fetchB(), fetchC()}
results := io.SequenceArray(operations)
values := results() // []int with all results
func SequenceArraySeq ¶
SequenceArraySeq converts an array of IO computations into an IO of an array of results. All computations are executed sequentially (one after another).
func SequenceParT1 ¶
SequenceParT1 converts 1 [IO[T]] into a [IO[tuple.Tuple1[T1]]]
func SequenceParT10 ¶
func SequenceParT10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], t8 IO[T8], t9 IO[T9], t10 IO[T10], ) IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
SequenceParT10 converts 10 [IO[T]] into a [IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func SequenceParT2 ¶
SequenceParT2 converts 2 [IO[T]] into a [IO[tuple.Tuple2[T1, T2]]]
func SequenceParT3 ¶
SequenceParT3 converts 3 [IO[T]] into a [IO[tuple.Tuple3[T1, T2, T3]]]
func SequenceParT4 ¶
func SequenceParT4[T1, T2, T3, T4 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], ) IO[tuple.Tuple4[T1, T2, T3, T4]]
SequenceParT4 converts 4 [IO[T]] into a [IO[tuple.Tuple4[T1, T2, T3, T4]]]
func SequenceParT5 ¶
func SequenceParT5[T1, T2, T3, T4, T5 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], ) IO[tuple.Tuple5[T1, T2, T3, T4, T5]]
SequenceParT5 converts 5 [IO[T]] into a [IO[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func SequenceParT6 ¶
func SequenceParT6[T1, T2, T3, T4, T5, T6 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], ) IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
SequenceParT6 converts 6 [IO[T]] into a [IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func SequenceParT7 ¶
func SequenceParT7[T1, T2, T3, T4, T5, T6, T7 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], ) IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
SequenceParT7 converts 7 [IO[T]] into a [IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func SequenceParT8 ¶
func SequenceParT8[T1, T2, T3, T4, T5, T6, T7, T8 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], t8 IO[T8], ) IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
SequenceParT8 converts 8 [IO[T]] into a [IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func SequenceParT9 ¶
func SequenceParT9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], t8 IO[T8], t9 IO[T9], ) IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
SequenceParT9 converts 9 [IO[T]] into a [IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func SequenceParTuple1 ¶
SequenceParTuple1 converts a [tuple.Tuple1[IO[T]]] into a [IO[tuple.Tuple1[T1]]]
func SequenceParTuple10 ¶
func SequenceParTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t tuple.Tuple10[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6], IO[T7], IO[T8], IO[T9], IO[T10]]) IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
SequenceParTuple10 converts a [tuple.Tuple10[IO[T]]] into a [IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func SequenceParTuple2 ¶
SequenceParTuple2 converts a [tuple.Tuple2[IO[T]]] into a [IO[tuple.Tuple2[T1, T2]]]
func SequenceParTuple3 ¶
func SequenceParTuple3[T1, T2, T3 any](t tuple.Tuple3[IO[T1], IO[T2], IO[T3]]) IO[tuple.Tuple3[T1, T2, T3]]
SequenceParTuple3 converts a [tuple.Tuple3[IO[T]]] into a [IO[tuple.Tuple3[T1, T2, T3]]]
func SequenceParTuple4 ¶
func SequenceParTuple4[T1, T2, T3, T4 any](t tuple.Tuple4[IO[T1], IO[T2], IO[T3], IO[T4]]) IO[tuple.Tuple4[T1, T2, T3, T4]]
SequenceParTuple4 converts a [tuple.Tuple4[IO[T]]] into a [IO[tuple.Tuple4[T1, T2, T3, T4]]]
func SequenceParTuple5 ¶
func SequenceParTuple5[T1, T2, T3, T4, T5 any](t tuple.Tuple5[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5]]) IO[tuple.Tuple5[T1, T2, T3, T4, T5]]
SequenceParTuple5 converts a [tuple.Tuple5[IO[T]]] into a [IO[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func SequenceParTuple6 ¶
func SequenceParTuple6[T1, T2, T3, T4, T5, T6 any](t tuple.Tuple6[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6]]) IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
SequenceParTuple6 converts a [tuple.Tuple6[IO[T]]] into a [IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func SequenceParTuple7 ¶
func SequenceParTuple7[T1, T2, T3, T4, T5, T6, T7 any](t tuple.Tuple7[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6], IO[T7]]) IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
SequenceParTuple7 converts a [tuple.Tuple7[IO[T]]] into a [IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func SequenceParTuple8 ¶
func SequenceParTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](t tuple.Tuple8[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6], IO[T7], IO[T8]]) IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
SequenceParTuple8 converts a [tuple.Tuple8[IO[T]]] into a [IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func SequenceParTuple9 ¶
func SequenceParTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t tuple.Tuple9[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6], IO[T7], IO[T8], IO[T9]]) IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
SequenceParTuple9 converts a [tuple.Tuple9[IO[T]]] into a [IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func SequenceRecord ¶
func SequenceRecord[K comparable, A any](tas map[K]IO[A]) IO[map[K]A]
SequenceRecord converts a map of IO computations into an IO of a map of results. All computations are executed in parallel by default.
Example:
operations := map[string]io.IO[int]{"a": fetchA(), "b": fetchB()}
results := io.SequenceRecord(operations)
values := results() // map[string]int with all results
func SequenceRecordSeq ¶
func SequenceRecordSeq[K comparable, A any](tas map[K]IO[A]) IO[map[K]A]
SequenceRecordSeq converts a map of IO computations into an IO of a map of results. All computations are executed sequentially (one after another).
func SequenceSeqT1 ¶
SequenceSeqT1 converts 1 [IO[T]] into a [IO[tuple.Tuple1[T1]]]
func SequenceSeqT10 ¶
func SequenceSeqT10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], t8 IO[T8], t9 IO[T9], t10 IO[T10], ) IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
SequenceSeqT10 converts 10 [IO[T]] into a [IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func SequenceSeqT2 ¶
SequenceSeqT2 converts 2 [IO[T]] into a [IO[tuple.Tuple2[T1, T2]]]
func SequenceSeqT3 ¶
SequenceSeqT3 converts 3 [IO[T]] into a [IO[tuple.Tuple3[T1, T2, T3]]]
func SequenceSeqT4 ¶
func SequenceSeqT4[T1, T2, T3, T4 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], ) IO[tuple.Tuple4[T1, T2, T3, T4]]
SequenceSeqT4 converts 4 [IO[T]] into a [IO[tuple.Tuple4[T1, T2, T3, T4]]]
func SequenceSeqT5 ¶
func SequenceSeqT5[T1, T2, T3, T4, T5 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], ) IO[tuple.Tuple5[T1, T2, T3, T4, T5]]
SequenceSeqT5 converts 5 [IO[T]] into a [IO[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func SequenceSeqT6 ¶
func SequenceSeqT6[T1, T2, T3, T4, T5, T6 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], ) IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
SequenceSeqT6 converts 6 [IO[T]] into a [IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func SequenceSeqT7 ¶
func SequenceSeqT7[T1, T2, T3, T4, T5, T6, T7 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], ) IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
SequenceSeqT7 converts 7 [IO[T]] into a [IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func SequenceSeqT8 ¶
func SequenceSeqT8[T1, T2, T3, T4, T5, T6, T7, T8 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], t8 IO[T8], ) IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
SequenceSeqT8 converts 8 [IO[T]] into a [IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func SequenceSeqT9 ¶
func SequenceSeqT9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], t8 IO[T8], t9 IO[T9], ) IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
SequenceSeqT9 converts 9 [IO[T]] into a [IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func SequenceSeqTuple1 ¶
SequenceSeqTuple1 converts a [tuple.Tuple1[IO[T]]] into a [IO[tuple.Tuple1[T1]]]
func SequenceSeqTuple10 ¶
func SequenceSeqTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t tuple.Tuple10[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6], IO[T7], IO[T8], IO[T9], IO[T10]]) IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
SequenceSeqTuple10 converts a [tuple.Tuple10[IO[T]]] into a [IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func SequenceSeqTuple2 ¶
SequenceSeqTuple2 converts a [tuple.Tuple2[IO[T]]] into a [IO[tuple.Tuple2[T1, T2]]]
func SequenceSeqTuple3 ¶
func SequenceSeqTuple3[T1, T2, T3 any](t tuple.Tuple3[IO[T1], IO[T2], IO[T3]]) IO[tuple.Tuple3[T1, T2, T3]]
SequenceSeqTuple3 converts a [tuple.Tuple3[IO[T]]] into a [IO[tuple.Tuple3[T1, T2, T3]]]
func SequenceSeqTuple4 ¶
func SequenceSeqTuple4[T1, T2, T3, T4 any](t tuple.Tuple4[IO[T1], IO[T2], IO[T3], IO[T4]]) IO[tuple.Tuple4[T1, T2, T3, T4]]
SequenceSeqTuple4 converts a [tuple.Tuple4[IO[T]]] into a [IO[tuple.Tuple4[T1, T2, T3, T4]]]
func SequenceSeqTuple5 ¶
func SequenceSeqTuple5[T1, T2, T3, T4, T5 any](t tuple.Tuple5[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5]]) IO[tuple.Tuple5[T1, T2, T3, T4, T5]]
SequenceSeqTuple5 converts a [tuple.Tuple5[IO[T]]] into a [IO[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func SequenceSeqTuple6 ¶
func SequenceSeqTuple6[T1, T2, T3, T4, T5, T6 any](t tuple.Tuple6[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6]]) IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
SequenceSeqTuple6 converts a [tuple.Tuple6[IO[T]]] into a [IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func SequenceSeqTuple7 ¶
func SequenceSeqTuple7[T1, T2, T3, T4, T5, T6, T7 any](t tuple.Tuple7[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6], IO[T7]]) IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
SequenceSeqTuple7 converts a [tuple.Tuple7[IO[T]]] into a [IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func SequenceSeqTuple8 ¶
func SequenceSeqTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](t tuple.Tuple8[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6], IO[T7], IO[T8]]) IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
SequenceSeqTuple8 converts a [tuple.Tuple8[IO[T]]] into a [IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func SequenceSeqTuple9 ¶
func SequenceSeqTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t tuple.Tuple9[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6], IO[T7], IO[T8], IO[T9]]) IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
SequenceSeqTuple9 converts a [tuple.Tuple9[IO[T]]] into a [IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func SequenceT1 ¶
SequenceT1 converts 1 [IO[T]] into a [IO[tuple.Tuple1[T1]]]
func SequenceT10 ¶
func SequenceT10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], t8 IO[T8], t9 IO[T9], t10 IO[T10], ) IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
SequenceT10 converts 10 [IO[T]] into a [IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func SequenceT2 ¶
SequenceT2 converts 2 [IO[T]] into a [IO[tuple.Tuple2[T1, T2]]]
func SequenceT3 ¶
SequenceT3 converts 3 [IO[T]] into a [IO[tuple.Tuple3[T1, T2, T3]]]
func SequenceT4 ¶
func SequenceT4[T1, T2, T3, T4 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], ) IO[tuple.Tuple4[T1, T2, T3, T4]]
SequenceT4 converts 4 [IO[T]] into a [IO[tuple.Tuple4[T1, T2, T3, T4]]]
func SequenceT5 ¶
func SequenceT5[T1, T2, T3, T4, T5 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], ) IO[tuple.Tuple5[T1, T2, T3, T4, T5]]
SequenceT5 converts 5 [IO[T]] into a [IO[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func SequenceT6 ¶
func SequenceT6[T1, T2, T3, T4, T5, T6 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], ) IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
SequenceT6 converts 6 [IO[T]] into a [IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func SequenceT7 ¶
func SequenceT7[T1, T2, T3, T4, T5, T6, T7 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], ) IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
SequenceT7 converts 7 [IO[T]] into a [IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func SequenceT8 ¶
func SequenceT8[T1, T2, T3, T4, T5, T6, T7, T8 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], t8 IO[T8], ) IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
SequenceT8 converts 8 [IO[T]] into a [IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func SequenceT9 ¶
func SequenceT9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any]( t1 IO[T1], t2 IO[T2], t3 IO[T3], t4 IO[T4], t5 IO[T5], t6 IO[T6], t7 IO[T7], t8 IO[T8], t9 IO[T9], ) IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
SequenceT9 converts 9 [IO[T]] into a [IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func SequenceTuple1 ¶
SequenceTuple1 converts a [tuple.Tuple1[IO[T]]] into a [IO[tuple.Tuple1[T1]]]
func SequenceTuple10 ¶
func SequenceTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t tuple.Tuple10[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6], IO[T7], IO[T8], IO[T9], IO[T10]]) IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
SequenceTuple10 converts a [tuple.Tuple10[IO[T]]] into a [IO[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func SequenceTuple2 ¶
SequenceTuple2 converts a [tuple.Tuple2[IO[T]]] into a [IO[tuple.Tuple2[T1, T2]]]
func SequenceTuple3 ¶
func SequenceTuple3[T1, T2, T3 any](t tuple.Tuple3[IO[T1], IO[T2], IO[T3]]) IO[tuple.Tuple3[T1, T2, T3]]
SequenceTuple3 converts a [tuple.Tuple3[IO[T]]] into a [IO[tuple.Tuple3[T1, T2, T3]]]
func SequenceTuple4 ¶
func SequenceTuple4[T1, T2, T3, T4 any](t tuple.Tuple4[IO[T1], IO[T2], IO[T3], IO[T4]]) IO[tuple.Tuple4[T1, T2, T3, T4]]
SequenceTuple4 converts a [tuple.Tuple4[IO[T]]] into a [IO[tuple.Tuple4[T1, T2, T3, T4]]]
func SequenceTuple5 ¶
func SequenceTuple5[T1, T2, T3, T4, T5 any](t tuple.Tuple5[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5]]) IO[tuple.Tuple5[T1, T2, T3, T4, T5]]
SequenceTuple5 converts a [tuple.Tuple5[IO[T]]] into a [IO[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func SequenceTuple6 ¶
func SequenceTuple6[T1, T2, T3, T4, T5, T6 any](t tuple.Tuple6[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6]]) IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
SequenceTuple6 converts a [tuple.Tuple6[IO[T]]] into a [IO[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func SequenceTuple7 ¶
func SequenceTuple7[T1, T2, T3, T4, T5, T6, T7 any](t tuple.Tuple7[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6], IO[T7]]) IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
SequenceTuple7 converts a [tuple.Tuple7[IO[T]]] into a [IO[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func SequenceTuple8 ¶
func SequenceTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](t tuple.Tuple8[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6], IO[T7], IO[T8]]) IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
SequenceTuple8 converts a [tuple.Tuple8[IO[T]]] into a [IO[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func SequenceTuple9 ¶
func SequenceTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t tuple.Tuple9[IO[T1], IO[T2], IO[T3], IO[T4], IO[T5], IO[T6], IO[T7], IO[T8], IO[T9]]) IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
SequenceTuple9 converts a [tuple.Tuple9[IO[T]]] into a [IO[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func WithDuration ¶
WithDuration returns an IO that measures the execution time.Duration of the operation. Returns a Pair with the duration as the head and the result as the tail. The result is placed in the tail position because that is the value that the pair monad operates on, allowing monadic operations to transform the result while preserving the duration.
Example:
timed := io.WithDuration(expensiveComputation)
p := timed()
duration := pair.Head(p)
result := pair.Tail(p)
fmt.Printf("Took %v\n", duration)
func WithTime ¶
WithTime returns an IO that measures the start and end time.Time of the operation. Returns a Pair[Pair[time.Time, time.Time], A] where the head contains a nested pair of (start time, end time) and the tail contains the result. The result is placed in the tail position because that is the value that the pair monad operates on, allowing monadic operations to transform the result while preserving the timing information.
Example:
timed := io.WithTime(expensiveComputation) p := timed() times := pair.Head(p) // Pair[time.Time, time.Time] result := pair.Tail(p) // A start := pair.Head(times) // time.Time end := pair.Tail(times) // time.Time
type IOApplicative ¶
type IOApplicative[A, B any] = applicative.Applicative[A, B, IO[A], IO[B], IO[func(A) B]]
IOApplicative represents the applicative functor type class for IO. It combines the capabilities of Functor (Map) and Pointed (Of) with the ability to apply wrapped functions to wrapped values (Ap).
func Applicative ¶
func Applicative[A, B any]() IOApplicative[A, B]
Applicative returns an instance of the Applicative type class for IO. This provides a structured way to access applicative operations (Of, Map, Ap) for IO computations.
Example:
app := io.Applicative[int, string]() result := app.Map(strconv.Itoa)(app.Of(42))
type IOFunctor ¶
IOFunctor represents the functor type class for IO. A functor allows mapping a function over a wrapped value without unwrapping it, preserving the structure.
type IOMonad ¶
IOMonad represents the monad type class for IO. A monad combines the capabilities of Functor, Applicative, and Pointed with the ability to chain computations (Chain/FlatMap).
func Monad ¶
func Monad[A, B any]() IOMonad[A, B]
Monad returns an instance of the Monad type class for IO. This provides a structured way to access monadic operations (Of, Map, Chain, Ap) for IO computations.
Example:
m := io.Monad[int, string]()
result := m.Chain(func(n int) io.IO[string] {
return io.Of(strconv.Itoa(n))
})(m.Of(42))
type IOPointed ¶
IOPointed represents the pointed functor type class for IO. A pointed functor is a functor with the ability to lift a pure value into the functor context (Of operation).
type Kleisli ¶
func FromConsumerK ¶
func FromConsumerK[A any](c Consumer[A]) Kleisli[A, struct{}]
FromConsumerK converts a Consumer into a Kleisli arrow that wraps the consumer in an IO context.
This function lifts a Consumer[A] (a function that consumes a value and performs side effects) into a Kleisli[A, struct{}] (a function that takes a value and returns an IO computation that performs the side effect and returns an empty struct).
The resulting Kleisli arrow can be used with Chain and other monadic operations to integrate consumers into IO pipelines. This is a lower-level function compared to ChainConsumer, which directly returns an Operator.
Type Parameters:
- A: The type of value consumed by the consumer
Parameters:
- c: A Consumer[A] that performs side effects on values of type A
Returns:
- A Kleisli[A, struct{}] that wraps the consumer in an IO context
Example:
// Create a consumer
logger := func(x int) {
fmt.Printf("Logging: %d\n", x)
}
// Convert to Kleisli arrow
logKleisli := io.FromConsumerK(logger)
// Use with Chain
result := F.Pipe2(
io.Of(42),
io.Chain(logKleisli), // Logs "Logging: 42"
io.Map(func(struct{}) string { return "completed" }),
)
result() // Returns "completed"
// Can also be used to build more complex operations
logAndCount := func(x int) io.IO[int] {
return F.Pipe2(
logKleisli(x),
io.Map(func(struct{}) int { return 1 }),
)
}
func LogGo ¶
LogGo constructs a logger function using Go template syntax for formatting. The prefix string is parsed as a Go template and executed with the value as data. Both successful output and template errors are logged using log.Println.
Example:
type User struct {
Name string
Age int
}
result := pipe.Pipe2(
fetchUser(),
io.ChainFirst(io.LogGo[User]("User: {{.Name}}, Age: {{.Age}}")),
processUser,
)
func Logf ¶
Logf constructs a logger function that can be used with ChainFirst or similar operations. The prefix string contains the format string for the log value.
Example:
result := pipe.Pipe2(
fetchUser(),
io.ChainFirst(io.Logf[User]("User: %+v")),
processUser,
)
func PrintGo ¶
PrintGo constructs a printer function using Go template syntax for formatting. The prefix string is parsed as a Go template and executed with the value as data. Successful output is printed to stdout using fmt.Println, while template errors are printed to stderr using fmt.Fprintln.
Example:
type User struct {
Name string
Age int
}
result := pipe.Pipe2(
fetchUser(),
io.ChainFirst(io.PrintGo[User]("User: {{.Name}}, Age: {{.Age}}")),
processUser,
)
func Printf ¶
Printf constructs a printer function that can be used with ChainFirst or similar operations. The prefix string contains the format string for the printed value. Unlike Logf, this prints to stdout without log prefixes.
Example:
result := pipe.Pipe2(
fetchUser(),
io.ChainFirst(io.Printf[User]("User: %+v\n")),
processUser,
)
func TraverseArray ¶
func TraverseArray[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B]
TraverseArray returns a function that applies an IO-returning function to each element of an array and collects the results. This is the curried version of MonadTraverseArray. Executes in parallel by default.
Example:
fetchUsers := io.TraverseArray(func(id int) io.IO[User] {
return fetchUser(id)
})
users := fetchUsers([]int{1, 2, 3})
func TraverseArraySeq ¶
func TraverseArraySeq[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B]
TraverseArraySeq returns a function that applies an IO-returning function to each element of an array and collects the results. Executes sequentially (one after another). Use this when operations must be performed in order or when parallel execution is not desired.
func TraverseArrayWithIndex ¶
TraverseArrayWithIndex is like TraverseArray but the function also receives the index. Executes in parallel by default.
Example:
numbered := io.TraverseArrayWithIndex(func(i int, s string) io.IO[string] {
return io.Of(fmt.Sprintf("%d: %s", i, s))
})
func TraverseArrayWithIndexSeq ¶
TraverseArrayWithIndexSeq is like TraverseArraySeq but the function also receives the index. Executes sequentially (one after another).
func TraverseIter ¶
func TraverseIter[A, B any](f Kleisli[A, B]) Kleisli[Seq[A], Seq[B]]
func TraverseParTuple1 ¶
func TraverseParTuple1[F1 ~Kleisli[A1, T1], T1, A1 any](f1 F1) Kleisli[tuple.Tuple1[A1], tuple.Tuple1[T1]]
TraverseParTuple1 converts a [tuple.Tuple1[A1]] into a [IO[tuple.Tuple1[T1]]]
func TraverseRecord ¶
func TraverseRecord[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B]
TraverseRecord returns a function that applies an IO-returning function to each value in a map and collects the results. This is the curried version of MonadTraverseRecord. Executes in parallel by default.
func TraverseRecordSeq ¶
func TraverseRecordSeq[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B]
TraverseRecordSeq returns a function that applies an IO-returning function to each value in a map and collects the results. Executes sequentially (one after another).
func TraverseRecordWithIndeSeq ¶
func TraverseRecordWithIndeSeq[K comparable, A, B any](f func(K, A) IO[B]) Kleisli[map[K]A, map[K]B]
TraverseRecordWithIndeSeq is like TraverseRecordSeq but the function also receives the key. Executes sequentially (one after another). Note: There's a typo in the function name (Inde instead of Index) for backward compatibility.
func TraverseRecordWithIndex ¶
func TraverseRecordWithIndex[K comparable, A, B any](f func(K, A) IO[B]) Kleisli[map[K]A, map[K]B]
TraverseRecordWithIndex is like TraverseRecord but the function also receives the key. Executes in parallel by default.
func TraverseSeqTuple1 ¶
func TraverseSeqTuple1[F1 ~Kleisli[A1, T1], T1, A1 any](f1 F1) Kleisli[tuple.Tuple1[A1], tuple.Tuple1[T1]]
TraverseSeqTuple1 converts a [tuple.Tuple1[A1]] into a [IO[tuple.Tuple1[T1]]]
func TraverseTuple1 ¶
func TraverseTuple1[F1 ~Kleisli[A1, T1], T1, A1 any](f1 F1) Kleisli[tuple.Tuple1[A1], tuple.Tuple1[T1]]
TraverseTuple1 converts a [tuple.Tuple1[A1]] into a [IO[tuple.Tuple1[T1]]]
func WithResource ¶
func WithResource[ R, A, ANY any](onCreate IO[R], onRelease func(R) IO[ANY]) Kleisli[Kleisli[R, A], A]
WithResource constructs a function that creates a resource, operates on it, and then releases it. This is a higher-level abstraction over Bracket that simplifies resource management patterns.
The resource is guaranteed to be released even if the operation fails or panics.
Example:
withFile := io.WithResource(
io.Of(openFile("data.txt")),
func(f *os.File) io.IO[any] {
return io.FromImpure(func() { f.Close() })
},
)
result := withFile(func(f *os.File) io.IO[Data] {
return readData(f)
})
type Monoid ¶
func ApplicativeMonoid ¶
ApplicativeMonoid lifts a Monoid[A] into a Monoid[IO[A]]. This allows combining IO computations using the monoid operation on their results, including an empty/identity element.
Example:
intAdd := monoid.MakeMonoid(func(a, b int) int { return a + b }, 0)
ioAdd := io.ApplicativeMonoid(intAdd)
result := ioAdd.Concat(io.Of(1), io.Of(2)) // IO[3]
empty := ioAdd.Empty() // IO[0]
type Operator ¶
func After ¶
After creates an operator that delays execution until after the given timestamp. If the timestamp is in the past, the computation executes immediately.
Example:
future := time.Now().Add(5 * time.Second) scheduled := io.After(future)(io.Of(42)) result := scheduled() // waits until future time, then returns 42
func Ap ¶
Ap returns an operator that applies a function wrapped in IO to a value wrapped in IO. This is the curried version of MonadAp and uses parallel execution by default.
Example:
add := func(a int) func(int) int { return func(b int) int { return a + b } }
result := io.Ap(io.Of(2))(io.Of(add(3))) // parallel execution
func ApPar ¶
ApPar returns an operator that applies a function wrapped in IO to a value wrapped in IO in parallel. This explicitly uses parallel execution (same as Ap when useParallel is true).
func ApS ¶
ApS attaches a value to a context S1 to produce a context S2 by considering the context and the value concurrently (using applicative operations). This allows parallel execution of independent computations.
Example:
io.ApS(func(posts []Post) func(s State) State {
return func(s State) State {
s.posts = posts
return s
}
}, fetchPosts())
func ApSL ¶
ApSL attaches a value to a context using a lens-based setter. This is a convenience function that combines ApS with a lens, allowing you to use optics to update nested structures in a more composable way.
The lens parameter provides both the getter and setter for a field within the structure S. This eliminates the need to manually write setter functions.
Example:
type Config struct {
Host string
Port int
}
portLens := lens.MakeLens(
func(c Config) int { return c.Port },
func(c Config, p int) Config { c.Port = p; return c },
)
result := F.Pipe2(
io.Of(Config{Host: "localhost"}),
io.ApSL(portLens, io.Of(8080)),
)
func ApSeq ¶
ApSeq returns an operator that applies a function wrapped in IO to a value wrapped in IO sequentially. Unlike Ap, this executes the function and value computations in sequence.
func Bind ¶
func Bind[S1, S2, T any]( setter func(T) func(S1) S2, f Kleisli[S1, T], ) Operator[S1, S2]
Bind attaches the result of an IO computation to a context S1 to produce a context S2. This is used in do-notation style composition to build up state incrementally.
The setter function takes the result T and returns a function that updates S1 to S2.
Example:
io.Bind(func(user User) func(s State) State {
return func(s State) State {
s.user = user
return s
}
}, fetchUser)
func BindL ¶
BindL attaches the result of a computation to a context using a lens-based setter. This is a convenience function that combines Bind with a lens, allowing you to use optics to update nested structures based on their current values.
The lens parameter provides both the getter and setter for a field within the structure S. The computation function f receives the current value of the focused field and returns an IO that produces the new value.
Example:
type Counter struct {
Value int
}
valueLens := lens.MakeLens(
func(c Counter) int { return c.Value },
func(c Counter, v int) Counter { c.Value = v; return c },
)
// Increment the counter asynchronously
increment := func(v int) io.IO[int] {
return io.Of(v + 1)
}
result := F.Pipe1(
io.Of(Counter{Value: 42}),
io.BindL(valueLens, increment),
) // IO[Counter{Value: 43}]
func BindTo ¶
func BindTo[S1, T any]( setter func(T) S1, ) Operator[T, S1]
BindTo initializes a new state S1 from a value T. This is typically used to start a do-notation chain from a single value.
Example:
io.BindTo(func(user User) State {
return State{user: user}
})
func Chain ¶
func Chain[A, B any](f Kleisli[A, B]) Operator[A, B]
Chain composes computations in sequence, using the return value of one computation to determine the next computation.
func ChainConsumer ¶
func ChainConsumer[A any](c Consumer[A]) Operator[A, struct{}]
ChainConsumer converts a Consumer into an IO operator that executes the consumer as a side effect and returns an empty struct.
This function bridges the gap between pure consumers (functions that consume values without returning anything) and the IO monad. It takes a Consumer[A] and returns an Operator that:
- Executes the source IO[A] to get a value
- Passes that value to the consumer for side effects
- Returns IO[struct{}] to maintain the monadic chain
The returned IO[struct{}] allows the operation to be composed with other IO operations while discarding the consumed value. This is useful for operations like logging, printing, or updating external state within an IO pipeline.
Type Parameters:
- A: The type of value consumed by the consumer
Parameters:
- c: A Consumer[A] that performs side effects on values of type A
Returns:
- An Operator[A, struct{}] that executes the consumer and returns an empty struct
Example:
// Create a consumer that logs values
logger := func(x int) {
fmt.Printf("Value: %d\n", x)
}
// Convert it to an IO operator
logOp := io.ChainConsumer(logger)
// Use it in an IO pipeline
result := F.Pipe2(
io.Of(42),
logOp, // Logs "Value: 42"
io.Map(func(struct{}) string { return "done" }),
)
result() // Returns "done" after logging
// Another example with multiple operations
var values []int
collector := func(x int) {
values = append(values, x)
}
pipeline := F.Pipe2(
io.Of(100),
io.ChainConsumer(collector), // Collects the value
io.Map(func(struct{}) int { return len(values) }),
)
count := pipeline() // Returns 1, values contains [100]
func ChainFirst ¶
func ChainFirst[A, B any](f Kleisli[A, B]) Operator[A, A]
ChainFirst composes computations in sequence, using the return value of one computation to determine the next computation and keeping only the result of the first.
func ChainTo ¶
ChainTo composes computations in sequence, ignoring the return value of the first computation
func Delay ¶
Delay creates an operator that delays execution by the specified duration. The delay occurs before executing the wrapped computation.
Example:
delayed := io.Delay(time.Second)(io.Of(42)) result := delayed() // waits 1 second, then returns 42
func Flap ¶
func Flap[B, A any](a A) Operator[func(A) B, B]
Flap returns an operator that applies a pure value to a function wrapped in IO. This is the curried version of MonadFlap.
func Let ¶
func Let[S1, S2, T any]( setter func(T) func(S1) S2, f func(S1) T, ) Operator[S1, S2]
Let attaches the result of a pure computation to a context S1 to produce a context S2. Similar to Bind, but for pure (non-IO) computations.
Example:
io.Let(func(count int) func(s State) State {
return func(s State) State {
s.count = count
return s
}
}, func(s State) int { return len(s.items) })
func LetL ¶
LetL attaches the result of a pure computation to a context using a lens-based setter. This is a convenience function that combines Let with a lens, allowing you to use optics to update nested structures with pure transformations.
The lens parameter provides both the getter and setter for a field within the structure S. The transformation function f receives the current value of the focused field and returns the new value directly (not wrapped in IO).
Example:
type Counter struct {
Value int
}
valueLens := lens.MakeLens(
func(c Counter) int { return c.Value },
func(c Counter, v int) Counter { c.Value = v; return c },
)
// Double the counter value
double := func(v int) int { return v * 2 }
result := F.Pipe1(
io.Of(Counter{Value: 21}),
io.LetL(valueLens, double),
) // IO[Counter{Value: 42}]
func LetTo ¶
func LetTo[S1, S2, T any]( setter func(T) func(S1) S2, b T, ) Operator[S1, S2]
LetTo attaches a constant value to a context S1 to produce a context S2. Similar to Let, but with a constant value instead of a computation.
Example:
io.LetTo(func(status string) func(s State) State {
return func(s State) State {
s.status = status
return s
}
}, "ready")
func LetToL ¶
LetToL attaches a constant value to a context using a lens-based setter. This is a convenience function that combines LetTo with a lens, allowing you to use optics to set nested fields to specific values.
The lens parameter provides the setter for a field within the structure S. Unlike LetL which transforms the current value, LetToL simply replaces it with the provided constant value b.
Example:
type Config struct {
Debug bool
Timeout int
}
debugLens := lens.MakeLens(
func(c Config) bool { return c.Debug },
func(c Config, d bool) Config { c.Debug = d; return c },
)
result := F.Pipe1(
io.Of(Config{Debug: true, Timeout: 30}),
io.LetToL(debugLens, false),
) // IO[Config{Debug: false, Timeout: 30}]
type RetryStatus ¶
type RetryStatus = IO[R.RetryStatus]
RetryStatus is an IO computation that returns retry status information.
type Semigroup ¶
func ApplySemigroup ¶
ApplySemigroup lifts a Semigroup[A] into a Semigroup[IO[A]]. This allows combining IO computations using the semigroup operation on their results.
Example:
intAdd := semigroup.MakeSemigroup(func(a, b int) int { return a + b })
ioAdd := io.ApplySemigroup(intAdd)
result := ioAdd.Concat(io.Of(1), io.Of(2)) // IO[3]