// 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 io import ( "context" "sync" "testing" "time" F "github.com/IBM/fp-go/v2/function" M "github.com/IBM/fp-go/v2/monoid" N "github.com/IBM/fp-go/v2/number" S "github.com/IBM/fp-go/v2/semigroup" T "github.com/IBM/fp-go/v2/tuple" "github.com/stretchr/testify/assert" ) // Test FromIO func TestFromIO(t *testing.T) { io := Of(42) result := FromIO(io) assert.Equal(t, 42, result()) } // Test MonadOf func TestMonadOf(t *testing.T) { result := MonadOf(42) assert.Equal(t, 42, result()) } // Test MonadMapTo func TestMonadMapTo(t *testing.T) { result := MonadMapTo(Of(1), "hello") assert.Equal(t, "hello", result()) } // Test MapTo func TestMapTo(t *testing.T) { result := F.Pipe1(Of(1), MapTo[int]("hello")) assert.Equal(t, "hello", result()) } // Test MonadApSeq func TestMonadApSeq(t *testing.T) { f := Of(N.Mul(2)) result := MonadApSeq(f, Of(21)) assert.Equal(t, 42, result()) } // Test ApPar func TestApPar(t *testing.T) { f := Of(N.Mul(2)) result := F.Pipe1(f, ApPar[int](Of(21))) assert.Equal(t, 42, result()) } // Test MonadChainFirst func TestMonadChainFirst(t *testing.T) { sideEffect := 0 result := MonadChainFirst(Of(42), func(x int) IO[string] { sideEffect = x return Of("ignored") }) assert.Equal(t, 42, result()) assert.Equal(t, 42, sideEffect) } // Test ChainFirst func TestChainFirst(t *testing.T) { sideEffect := 0 result := F.Pipe1(Of(42), ChainFirst(func(x int) IO[string] { sideEffect = x return Of("ignored") })) assert.Equal(t, 42, result()) assert.Equal(t, 42, sideEffect) } // Test MonadApFirst func TestMonadApFirst(t *testing.T) { result := MonadApFirst(Of(42), Of("ignored")) assert.Equal(t, 42, result()) } // Test MonadApSecond func TestMonadApSecond(t *testing.T) { result := MonadApSecond(Of("ignored"), Of(42)) assert.Equal(t, 42, result()) } // Test MonadChainTo func TestMonadChainTo(t *testing.T) { result := MonadChainTo(Of(1), Of(42)) assert.Equal(t, 42, result()) } // Test ChainTo func TestChainTo(t *testing.T) { result := F.Pipe1(Of(1), ChainTo[int](Of(42))) assert.Equal(t, 42, result()) } // Test Defer func TestDefer(t *testing.T) { counter := 0 deferred := Defer(func() IO[int] { counter++ return Of(counter) }) assert.Equal(t, 1, deferred()) assert.Equal(t, 2, deferred()) assert.Equal(t, 3, deferred()) } // Test MonadFlap func TestMonadFlap(t *testing.T) { f := Of(N.Mul(2)) result := MonadFlap(f, 21) assert.Equal(t, 42, result()) } // Test Flap func TestFlap(t *testing.T) { f := Of(N.Mul(2)) result := F.Pipe1(f, Flap[int](21)) assert.Equal(t, 42, result()) } // Test After func TestAfter(t *testing.T) { future := time.Now().Add(50 * time.Millisecond) start := time.Now() result := F.Pipe1(Of(42), After[int](future)) value := result() elapsed := time.Since(start) assert.Equal(t, 42, value) assert.True(t, elapsed >= 50*time.Millisecond) } // Test WithTime func TestWithTime(t *testing.T) { result := WithTime(Of(42)) tuple := result() assert.Equal(t, 42, tuple.F1) assert.True(t, tuple.F2.Before(tuple.F3) || tuple.F2.Equal(tuple.F3)) } // Test WithDuration func TestWithDuration(t *testing.T) { result := WithDuration(func() int { time.Sleep(10 * time.Millisecond) return 42 }) tuple := result() assert.Equal(t, 42, tuple.F1) assert.True(t, tuple.F2 >= 10*time.Millisecond) } // Test Let func TestLet(t *testing.T) { type State struct { value int } result := F.Pipe2( Of(State{value: 10}), Let(func(doubled int) func(s State) State { return func(s State) State { s.value = doubled return s } }, func(s State) int { return s.value * 2 }), Map(func(s State) int { return s.value }), ) assert.Equal(t, 20, result()) } // Test LetTo func TestLetTo(t *testing.T) { type State struct { value int } result := F.Pipe2( Of(State{value: 10}), LetTo(func(newVal int) func(s State) State { return func(s State) State { s.value = newVal return s } }, 42), Map(func(s State) int { return s.value }), ) assert.Equal(t, 42, result()) } // Test BindTo func TestBindTo(t *testing.T) { type State struct { value int } result := F.Pipe2( Of(42), BindTo(func(v int) State { return State{value: v} }), Map(func(s State) int { return s.value }), ) assert.Equal(t, 42, result()) } // Test Bracket func TestBracket(t *testing.T) { acquired := false released := false acquire := func() int { acquired = true return 42 } use := func(x int) IO[int] { return Of(x * 2) } release := func(x int, result int) IO[any] { return FromImpure(func() { released = true }) } result := Bracket(Of(acquire()), use, release) value := result() assert.Equal(t, 84, value) assert.True(t, acquired) assert.True(t, released) } // Test WithResource func TestWithResource(t *testing.T) { acquired := false released := false onCreate := func() int { acquired = true return 42 } onRelease := func(x int) IO[any] { return FromImpure(func() { released = true }) } withRes := WithResource[int, int](Of(onCreate()), onRelease) result := withRes(func(x int) IO[int] { return Of(x * 2) }) value := result() assert.Equal(t, 84, value) assert.True(t, acquired) assert.True(t, released) } // Test WithLock - simplified test func TestWithLock(t *testing.T) { var mu sync.Mutex counter := 0 // Create a lock IO that acquires the lock and returns a release function lock := func() func() { mu.Lock() return func() { mu.Unlock() } } // Create operation that increments counter operation := func() int { counter++ return counter } // Apply lock to operation - cast to context.CancelFunc var lockIO IO[context.CancelFunc] = func() context.CancelFunc { return lock() } safeOp := WithLock[int](lockIO)(operation) // Run the operation result := safeOp() assert.Equal(t, 1, result) assert.Equal(t, 1, counter) } // Test Printf func TestPrintf(t *testing.T) { result := F.Pipe1(Of(42), ChainFirst(Printf[int]("Value: %d\n"))) assert.Equal(t, 42, result()) } // Test ApplySemigroup func TestApplySemigroup(t *testing.T) { intAdd := S.MakeSemigroup(func(a, b int) int { return a + b }) ioSemigroup := ApplySemigroup(intAdd) result := ioSemigroup.Concat(Of(10), Of(32)) assert.Equal(t, 42, result()) } // Test ApplicativeMonoid func TestApplicativeMonoid(t *testing.T) { intAdd := M.MakeMonoid(func(a, b int) int { return a + b }, 0) ioMonoid := ApplicativeMonoid(intAdd) result := ioMonoid.Concat(Of(10), Of(32)) assert.Equal(t, 42, result()) empty := ioMonoid.Empty() assert.Equal(t, 0, empty()) } // Test Applicative type class func TestApplicativeTypeClass(t *testing.T) { app := Applicative[int, int]() // Test Of io1 := app.Of(21) assert.Equal(t, 21, io1()) // Test Map io2 := app.Map(N.Mul(2))(io1) assert.Equal(t, 42, io2()) } // Test Monad type class func TestMonadTypeClass(t *testing.T) { m := Monad[int, int]() result := F.Pipe2( m.Of(21), m.Chain(func(x int) IO[int] { return m.Of(x * 2) }), m.Map(func(x int) int { return x + 1 }), ) assert.Equal(t, 43, result()) } // Test TraverseArrayWithIndex func TestTraverseArrayWithIndex(t *testing.T) { src := []string{"a", "b", "c"} result := F.Pipe1( src, TraverseArrayWithIndex(func(i int, s string) IO[string] { return Of(F.Pipe1(i, func(idx int) string { return s + string(rune('0'+idx)) })) }), ) assert.Equal(t, []string{"a0", "b1", "c2"}, result()) } // Test TraverseRecord func TestTraverseRecord(t *testing.T) { src := map[string]int{"a": 1, "b": 2} result := F.Pipe1( src, TraverseRecord[string](func(x int) IO[int] { return Of(x * 2) }), ) values := result() assert.Equal(t, 2, values["a"]) assert.Equal(t, 4, values["b"]) } // Test TraverseRecordWithIndex func TestTraverseRecordWithIndex(t *testing.T) { src := map[string]int{"a": 1, "b": 2} result := F.Pipe1( src, TraverseRecordWithIndex(func(k string, x int) IO[string] { return Of(k) }), ) values := result() assert.Equal(t, "a", values["a"]) assert.Equal(t, "b", values["b"]) } // Test SequenceRecord func TestSequenceRecord(t *testing.T) { src := map[string]IO[int]{ "a": Of(1), "b": Of(2), } result := SequenceRecord(src) values := result() assert.Equal(t, 1, values["a"]) assert.Equal(t, 2, values["b"]) } // Test MonadTraverseRecord func TestMonadTraverseRecord(t *testing.T) { src := map[string]int{"a": 1, "b": 2} result := MonadTraverseRecord(src, func(x int) IO[int] { return Of(x * 2) }) values := result() assert.Equal(t, 2, values["a"]) assert.Equal(t, 4, values["b"]) } // Test TraverseArrayWithIndexSeq func TestTraverseArrayWithIndexSeq(t *testing.T) { var order []int src := []int{1, 2, 3} result := F.Pipe1( src, TraverseArrayWithIndexSeq(func(i int, x int) IO[int] { return func() int { order = append(order, i) return x * 2 } }), ) values := result() assert.Equal(t, []int{2, 4, 6}, values) assert.Equal(t, []int{0, 1, 2}, order) // Sequential order } // Test SequenceArraySeq func TestSequenceArraySeq(t *testing.T) { var order []int src := []IO[int]{ func() int { order = append(order, 0); return 1 }, func() int { order = append(order, 1); return 2 }, func() int { order = append(order, 2); return 3 }, } result := SequenceArraySeq(src) values := result() assert.Equal(t, []int{1, 2, 3}, values) assert.Equal(t, []int{0, 1, 2}, order) // Sequential order } // Test MonadTraverseArraySeq func TestMonadTraverseArraySeq(t *testing.T) { var order []int src := []int{1, 2, 3} result := MonadTraverseArraySeq(src, func(x int) IO[int] { return func() int { order = append(order, x) return x * 2 } }) values := result() assert.Equal(t, []int{2, 4, 6}, values) assert.Equal(t, []int{1, 2, 3}, order) // Sequential order } // Test TraverseRecordSeq func TestTraverseRecordSeq(t *testing.T) { src := map[string]int{"a": 1, "b": 2} result := F.Pipe1( src, TraverseRecordSeq[string](func(x int) IO[int] { return Of(x * 2) }), ) values := result() assert.Equal(t, 2, values["a"]) assert.Equal(t, 4, values["b"]) } // Test TraverseRecordWithIndeSeq (note the typo in the function name) func TestTraverseRecordWithIndeSeq(t *testing.T) { src := map[string]int{"a": 1, "b": 2} result := F.Pipe1( src, TraverseRecordWithIndeSeq(func(k string, x int) IO[string] { return Of(k) }), ) values := result() assert.Equal(t, "a", values["a"]) assert.Equal(t, "b", values["b"]) } // Test SequenceRecordSeq func TestSequenceRecordSeq(t *testing.T) { src := map[string]IO[int]{ "a": Of(1), "b": Of(2), } result := SequenceRecordSeq(src) values := result() assert.Equal(t, 1, values["a"]) assert.Equal(t, 2, values["b"]) } // Test MonadTraverseRecordSeq func TestMonadTraverseRecordSeq(t *testing.T) { src := map[string]int{"a": 1, "b": 2} result := MonadTraverseRecordSeq(src, func(x int) IO[int] { return Of(x * 2) }) values := result() assert.Equal(t, 2, values["a"]) assert.Equal(t, 4, values["b"]) } // Test SequenceTuple2 func TestSequenceTuple2(t *testing.T) { io1 := Of(10) io2 := Of(32) tup := T.MakeTuple2(io1, io2) result := SequenceTuple2(tup) tuple := result() assert.Equal(t, 10, tuple.F1) assert.Equal(t, 32, tuple.F2) } // Test SequenceT2 func TestSequenceT2(t *testing.T) { result := SequenceT2(Of(10), Of(32)) tuple := result() assert.Equal(t, 10, tuple.F1) assert.Equal(t, 32, tuple.F2) } // Test SequenceTuple3 func TestSequenceTuple3(t *testing.T) { io1 := Of(10) io2 := Of(20) io3 := Of(30) tup := T.MakeTuple3(io1, io2, io3) result := SequenceTuple3(tup) tuple := result() assert.Equal(t, 10, tuple.F1) assert.Equal(t, 20, tuple.F2) assert.Equal(t, 30, tuple.F3) } // Test SequenceSeqTuple2 func TestSequenceSeqTuple2(t *testing.T) { var order []int io1 := func() int { order = append(order, 1); return 10 } io2 := func() int { order = append(order, 2); return 20 } tup := T.MakeTuple2(io1, io2) result := SequenceSeqTuple2(tup) tuple := result() assert.Equal(t, 10, tuple.F1) assert.Equal(t, 20, tuple.F2) assert.Equal(t, []int{1, 2}, order) // Sequential execution } // Test SequenceParTuple2 func TestSequenceParTuple2(t *testing.T) { io1 := Of(10) io2 := Of(20) tup := T.MakeTuple2(io1, io2) result := SequenceParTuple2(tup) tuple := result() assert.Equal(t, 10, tuple.F1) assert.Equal(t, 20, tuple.F2) } // Test SequenceT3 func TestSequenceT3(t *testing.T) { result := SequenceT3(Of(10), Of(20), Of(30)) tuple := result() assert.Equal(t, 10, tuple.F1) assert.Equal(t, 20, tuple.F2) assert.Equal(t, 30, tuple.F3) } // Test SequenceSeqT2 func TestSequenceSeqT2(t *testing.T) { var order []int io1 := func() int { order = append(order, 1); return 10 } io2 := func() int { order = append(order, 2); return 20 } result := SequenceSeqT2(io1, io2) tuple := result() assert.Equal(t, 10, tuple.F1) assert.Equal(t, 20, tuple.F2) assert.Equal(t, []int{1, 2}, order) } // Test SequenceParT2 func TestSequenceParT2(t *testing.T) { result := SequenceParT2(Of(10), Of(20)) tuple := result() assert.Equal(t, 10, tuple.F1) assert.Equal(t, 20, tuple.F2) } // Test SequenceT4 func TestSequenceT4(t *testing.T) { result := SequenceT4(Of(1), Of(2), Of(3), Of(4)) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) } // Test SequenceTuple4 func TestSequenceTuple4(t *testing.T) { tup := T.MakeTuple4(Of(1), Of(2), Of(3), Of(4)) result := SequenceTuple4(tup) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) } // Test SequenceT5 func TestSequenceT5(t *testing.T) { result := SequenceT5(Of(1), Of(2), Of(3), Of(4), Of(5)) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) } // Test TraverseTuple2 func TestTraverseTuple2(t *testing.T) { inputTuple := T.MakeTuple2(10, 20) result := TraverseTuple2( func(x int) IO[int] { return Of(x * 2) }, func(x int) IO[int] { return Of(x + 1) }, )(inputTuple) tuple := result() assert.Equal(t, 20, tuple.F1) assert.Equal(t, 21, tuple.F2) } // Test TraverseTuple3 func TestTraverseTuple3(t *testing.T) { inputTuple := T.MakeTuple3(10, 20, 30) result := TraverseTuple3( func(x int) IO[int] { return Of(x * 2) }, func(x int) IO[int] { return Of(x + 1) }, func(x int) IO[int] { return Of(x - 1) }, )(inputTuple) tuple := result() assert.Equal(t, 20, tuple.F1) assert.Equal(t, 21, tuple.F2) assert.Equal(t, 29, tuple.F3) } // Test SequenceTuple1 func TestSequenceTuple1(t *testing.T) { tup := T.MakeTuple1(Of(42)) result := SequenceTuple1(tup) tuple := result() assert.Equal(t, 42, tuple.F1) } // Test SequenceT1 func TestSequenceT1(t *testing.T) { result := SequenceT1(Of(42)) tuple := result() assert.Equal(t, 42, tuple.F1) } // Test SequenceSeqT3 func TestSequenceSeqT3(t *testing.T) { var order []int io1 := func() int { order = append(order, 1); return 10 } io2 := func() int { order = append(order, 2); return 20 } io3 := func() int { order = append(order, 3); return 30 } result := SequenceSeqT3(io1, io2, io3) tuple := result() assert.Equal(t, 10, tuple.F1) assert.Equal(t, 20, tuple.F2) assert.Equal(t, 30, tuple.F3) assert.Equal(t, []int{1, 2, 3}, order) } // Test SequenceParT3 func TestSequenceParT3(t *testing.T) { result := SequenceParT3(Of(10), Of(20), Of(30)) tuple := result() assert.Equal(t, 10, tuple.F1) assert.Equal(t, 20, tuple.F2) assert.Equal(t, 30, tuple.F3) } // Test TraverseSeqTuple3 func TestTraverseSeqTuple3(t *testing.T) { var order []int inputTuple := T.MakeTuple3(10, 20, 30) result := TraverseSeqTuple3( func(x int) IO[int] { return func() int { order = append(order, 1); return x * 2 } }, func(x int) IO[int] { return func() int { order = append(order, 2); return x + 1 } }, func(x int) IO[int] { return func() int { order = append(order, 3); return x - 1 } }, )(inputTuple) tuple := result() assert.Equal(t, 20, tuple.F1) assert.Equal(t, 21, tuple.F2) assert.Equal(t, 29, tuple.F3) assert.Equal(t, []int{1, 2, 3}, order) } // Test TraverseParTuple3 func TestTraverseParTuple3(t *testing.T) { inputTuple := T.MakeTuple3(10, 20, 30) result := TraverseParTuple3( func(x int) IO[int] { return Of(x * 2) }, func(x int) IO[int] { return Of(x + 1) }, func(x int) IO[int] { return Of(x - 1) }, )(inputTuple) tuple := result() assert.Equal(t, 20, tuple.F1) assert.Equal(t, 21, tuple.F2) assert.Equal(t, 29, tuple.F3) } // Test SequenceSeqTuple3 func TestSequenceSeqTuple3(t *testing.T) { var order []int io1 := func() int { order = append(order, 1); return 10 } io2 := func() int { order = append(order, 2); return 20 } io3 := func() int { order = append(order, 3); return 30 } tup := T.MakeTuple3(io1, io2, io3) result := SequenceSeqTuple3(tup) tuple := result() assert.Equal(t, 10, tuple.F1) assert.Equal(t, 20, tuple.F2) assert.Equal(t, 30, tuple.F3) assert.Equal(t, []int{1, 2, 3}, order) } // Test SequenceParTuple3 func TestSequenceParTuple3(t *testing.T) { tup := T.MakeTuple3(Of(10), Of(20), Of(30)) result := SequenceParTuple3(tup) tuple := result() assert.Equal(t, 10, tuple.F1) assert.Equal(t, 20, tuple.F2) assert.Equal(t, 30, tuple.F3) } // Test SequenceSeqT4 func TestSequenceSeqT4(t *testing.T) { var order []int io1 := func() int { order = append(order, 1); return 1 } io2 := func() int { order = append(order, 2); return 2 } io3 := func() int { order = append(order, 3); return 3 } io4 := func() int { order = append(order, 4); return 4 } result := SequenceSeqT4(io1, io2, io3, io4) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, []int{1, 2, 3, 4}, order) } // Test SequenceParT4 func TestSequenceParT4(t *testing.T) { result := SequenceParT4(Of(1), Of(2), Of(3), Of(4)) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) } // Test SequenceSeqTuple4 func TestSequenceSeqTuple4(t *testing.T) { var order []int io1 := func() int { order = append(order, 1); return 1 } io2 := func() int { order = append(order, 2); return 2 } io3 := func() int { order = append(order, 3); return 3 } io4 := func() int { order = append(order, 4); return 4 } tup := T.MakeTuple4(io1, io2, io3, io4) result := SequenceSeqTuple4(tup) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, []int{1, 2, 3, 4}, order) } // Test SequenceParTuple4 func TestSequenceParTuple4(t *testing.T) { tup := T.MakeTuple4(Of(1), Of(2), Of(3), Of(4)) result := SequenceParTuple4(tup) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) } // Test TraverseTuple4 func TestTraverseTuple4(t *testing.T) { inputTuple := T.MakeTuple4(1, 2, 3, 4) result := TraverseTuple4( func(x int) IO[int] { return Of(x * 10) }, func(x int) IO[int] { return Of(x * 20) }, func(x int) IO[int] { return Of(x * 30) }, func(x int) IO[int] { return Of(x * 40) }, )(inputTuple) tuple := result() assert.Equal(t, 10, tuple.F1) assert.Equal(t, 40, tuple.F2) assert.Equal(t, 90, tuple.F3) assert.Equal(t, 160, tuple.F4) } // Test SequenceSeqT5 func TestSequenceSeqT5(t *testing.T) { var order []int io1 := func() int { order = append(order, 1); return 1 } io2 := func() int { order = append(order, 2); return 2 } io3 := func() int { order = append(order, 3); return 3 } io4 := func() int { order = append(order, 4); return 4 } io5 := func() int { order = append(order, 5); return 5 } result := SequenceSeqT5(io1, io2, io3, io4, io5) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, []int{1, 2, 3, 4, 5}, order) } // Test SequenceParT5 func TestSequenceParT5(t *testing.T) { result := SequenceParT5(Of(1), Of(2), Of(3), Of(4), Of(5)) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) } // Test SequenceSeqTuple1 func TestSequenceSeqTuple1(t *testing.T) { var executed bool io1 := func() int { executed = true; return 42 } tup := T.MakeTuple1(io1) result := SequenceSeqTuple1(tup) tuple := result() assert.Equal(t, 42, tuple.F1) assert.True(t, executed) } // Test SequenceParTuple1 func TestSequenceParTuple1(t *testing.T) { tup := T.MakeTuple1(Of(42)) result := SequenceParTuple1(tup) tuple := result() assert.Equal(t, 42, tuple.F1) } // Test TraverseTuple1 func TestTraverseTuple1(t *testing.T) { inputTuple := T.MakeTuple1(21) result := TraverseTuple1( func(x int) IO[int] { return Of(x * 2) }, )(inputTuple) tuple := result() assert.Equal(t, 42, tuple.F1) } // Test TraverseSeqTuple1 func TestTraverseSeqTuple1(t *testing.T) { var executed bool inputTuple := T.MakeTuple1(21) result := TraverseSeqTuple1( func(x int) IO[int] { return func() int { executed = true; return x * 2 } }, )(inputTuple) tuple := result() assert.Equal(t, 42, tuple.F1) assert.True(t, executed) } // Test TraverseParTuple1 func TestTraverseParTuple1(t *testing.T) { inputTuple := T.MakeTuple1(21) result := TraverseParTuple1( func(x int) IO[int] { return Of(x * 2) }, )(inputTuple) tuple := result() assert.Equal(t, 42, tuple.F1) } // Test SequenceTuple5 func TestSequenceTuple5(t *testing.T) { tup := T.MakeTuple5(Of(1), Of(2), Of(3), Of(4), Of(5)) result := SequenceTuple5(tup) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) } // Test SequenceSeqTuple5 func TestSequenceSeqTuple5(t *testing.T) { var order []int io1 := func() int { order = append(order, 1); return 1 } io2 := func() int { order = append(order, 2); return 2 } io3 := func() int { order = append(order, 3); return 3 } io4 := func() int { order = append(order, 4); return 4 } io5 := func() int { order = append(order, 5); return 5 } tup := T.MakeTuple5(io1, io2, io3, io4, io5) result := SequenceSeqTuple5(tup) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, []int{1, 2, 3, 4, 5}, order) } // Test SequenceParTuple5 func TestSequenceParTuple5(t *testing.T) { tup := T.MakeTuple5(Of(1), Of(2), Of(3), Of(4), Of(5)) result := SequenceParTuple5(tup) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) } // Test TraverseTuple5 func TestTraverseTuple5(t *testing.T) { inputTuple := T.MakeTuple5(1, 2, 3, 4, 5) result := TraverseTuple5( func(x int) IO[int] { return Of(x * 10) }, func(x int) IO[int] { return Of(x * 20) }, func(x int) IO[int] { return Of(x * 30) }, func(x int) IO[int] { return Of(x * 40) }, func(x int) IO[int] { return Of(x * 50) }, )(inputTuple) tuple := result() assert.Equal(t, 10, tuple.F1) assert.Equal(t, 40, tuple.F2) assert.Equal(t, 90, tuple.F3) assert.Equal(t, 160, tuple.F4) assert.Equal(t, 250, tuple.F5) } // Test TraverseSeqTuple5 func TestTraverseSeqTuple5(t *testing.T) { var order []int inputTuple := T.MakeTuple5(1, 2, 3, 4, 5) result := TraverseSeqTuple5( func(x int) IO[int] { return func() int { order = append(order, 1); return x * 10 } }, func(x int) IO[int] { return func() int { order = append(order, 2); return x * 20 } }, func(x int) IO[int] { return func() int { order = append(order, 3); return x * 30 } }, func(x int) IO[int] { return func() int { order = append(order, 4); return x * 40 } }, func(x int) IO[int] { return func() int { order = append(order, 5); return x * 50 } }, )(inputTuple) tuple := result() assert.Equal(t, 10, tuple.F1) assert.Equal(t, 40, tuple.F2) assert.Equal(t, 90, tuple.F3) assert.Equal(t, 160, tuple.F4) assert.Equal(t, 250, tuple.F5) assert.Equal(t, []int{1, 2, 3, 4, 5}, order) } // Test TraverseParTuple5 func TestTraverseParTuple5(t *testing.T) { inputTuple := T.MakeTuple5(1, 2, 3, 4, 5) result := TraverseParTuple5( func(x int) IO[int] { return Of(x * 10) }, func(x int) IO[int] { return Of(x * 20) }, func(x int) IO[int] { return Of(x * 30) }, func(x int) IO[int] { return Of(x * 40) }, func(x int) IO[int] { return Of(x * 50) }, )(inputTuple) tuple := result() assert.Equal(t, 10, tuple.F1) assert.Equal(t, 40, tuple.F2) assert.Equal(t, 90, tuple.F3) assert.Equal(t, 160, tuple.F4) assert.Equal(t, 250, tuple.F5) } // Test SequenceT6 func TestSequenceT6(t *testing.T) { result := SequenceT6(Of(1), Of(2), Of(3), Of(4), Of(5), Of(6)) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) } // Test SequenceSeqT6 func TestSequenceSeqT6(t *testing.T) { var order []int io1 := func() int { order = append(order, 1); return 1 } io2 := func() int { order = append(order, 2); return 2 } io3 := func() int { order = append(order, 3); return 3 } io4 := func() int { order = append(order, 4); return 4 } io5 := func() int { order = append(order, 5); return 5 } io6 := func() int { order = append(order, 6); return 6 } result := SequenceSeqT6(io1, io2, io3, io4, io5, io6) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) assert.Equal(t, []int{1, 2, 3, 4, 5, 6}, order) } // Test SequenceParT6 func TestSequenceParT6(t *testing.T) { result := SequenceParT6(Of(1), Of(2), Of(3), Of(4), Of(5), Of(6)) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) } // Test SequenceT7 func TestSequenceT7(t *testing.T) { result := SequenceT7(Of(1), Of(2), Of(3), Of(4), Of(5), Of(6), Of(7)) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) assert.Equal(t, 7, tuple.F7) } // Test SequenceT8 func TestSequenceT8(t *testing.T) { result := SequenceT8(Of(1), Of(2), Of(3), Of(4), Of(5), Of(6), Of(7), Of(8)) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) assert.Equal(t, 7, tuple.F7) assert.Equal(t, 8, tuple.F8) } // Test SequenceT9 func TestSequenceT9(t *testing.T) { result := SequenceT9(Of(1), Of(2), Of(3), Of(4), Of(5), Of(6), Of(7), Of(8), Of(9)) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) assert.Equal(t, 7, tuple.F7) assert.Equal(t, 8, tuple.F8) assert.Equal(t, 9, tuple.F9) } // Test SequenceT10 func TestSequenceT10(t *testing.T) { result := SequenceT10(Of(1), Of(2), Of(3), Of(4), Of(5), Of(6), Of(7), Of(8), Of(9), Of(10)) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) assert.Equal(t, 7, tuple.F7) assert.Equal(t, 8, tuple.F8) assert.Equal(t, 9, tuple.F9) assert.Equal(t, 10, tuple.F10) } // Test SequenceTuple6 func TestSequenceTuple6(t *testing.T) { tup := T.MakeTuple6(Of(1), Of(2), Of(3), Of(4), Of(5), Of(6)) result := SequenceTuple6(tup) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) } // Test SequenceSeqTuple6 func TestSequenceSeqTuple6(t *testing.T) { var order []int io1 := func() int { order = append(order, 1); return 1 } io2 := func() int { order = append(order, 2); return 2 } io3 := func() int { order = append(order, 3); return 3 } io4 := func() int { order = append(order, 4); return 4 } io5 := func() int { order = append(order, 5); return 5 } io6 := func() int { order = append(order, 6); return 6 } tup := T.MakeTuple6(io1, io2, io3, io4, io5, io6) result := SequenceSeqTuple6(tup) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) assert.Equal(t, []int{1, 2, 3, 4, 5, 6}, order) } // Test SequenceParTuple6 func TestSequenceParTuple6(t *testing.T) { tup := T.MakeTuple6(Of(1), Of(2), Of(3), Of(4), Of(5), Of(6)) result := SequenceParTuple6(tup) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) } // Test TraverseTuple6 func TestTraverseTuple6(t *testing.T) { inputTuple := T.MakeTuple6(1, 2, 3, 4, 5, 6) result := TraverseTuple6( func(x int) IO[int] { return Of(x * 1) }, func(x int) IO[int] { return Of(x * 2) }, func(x int) IO[int] { return Of(x * 3) }, func(x int) IO[int] { return Of(x * 4) }, func(x int) IO[int] { return Of(x * 5) }, func(x int) IO[int] { return Of(x * 6) }, )(inputTuple) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 4, tuple.F2) assert.Equal(t, 9, tuple.F3) assert.Equal(t, 16, tuple.F4) assert.Equal(t, 25, tuple.F5) assert.Equal(t, 36, tuple.F6) } // Test SequenceTuple7 func TestSequenceTuple7(t *testing.T) { tup := T.MakeTuple7(Of(1), Of(2), Of(3), Of(4), Of(5), Of(6), Of(7)) result := SequenceTuple7(tup) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) assert.Equal(t, 7, tuple.F7) } // Test SequenceSeqT7 func TestSequenceSeqT7(t *testing.T) { var order []int io1 := func() int { order = append(order, 1); return 1 } io2 := func() int { order = append(order, 2); return 2 } io3 := func() int { order = append(order, 3); return 3 } io4 := func() int { order = append(order, 4); return 4 } io5 := func() int { order = append(order, 5); return 5 } io6 := func() int { order = append(order, 6); return 6 } io7 := func() int { order = append(order, 7); return 7 } result := SequenceSeqT7(io1, io2, io3, io4, io5, io6, io7) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) assert.Equal(t, 7, tuple.F7) assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7}, order) } // Test SequenceParT7 func TestSequenceParT7(t *testing.T) { result := SequenceParT7(Of(1), Of(2), Of(3), Of(4), Of(5), Of(6), Of(7)) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) assert.Equal(t, 7, tuple.F7) } // Test SequenceTuple8 func TestSequenceTuple8(t *testing.T) { tup := T.MakeTuple8(Of(1), Of(2), Of(3), Of(4), Of(5), Of(6), Of(7), Of(8)) result := SequenceTuple8(tup) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) assert.Equal(t, 7, tuple.F7) assert.Equal(t, 8, tuple.F8) } // Test SequenceSeqT8 func TestSequenceSeqT8(t *testing.T) { var order []int io1 := func() int { order = append(order, 1); return 1 } io2 := func() int { order = append(order, 2); return 2 } io3 := func() int { order = append(order, 3); return 3 } io4 := func() int { order = append(order, 4); return 4 } io5 := func() int { order = append(order, 5); return 5 } io6 := func() int { order = append(order, 6); return 6 } io7 := func() int { order = append(order, 7); return 7 } io8 := func() int { order = append(order, 8); return 8 } result := SequenceSeqT8(io1, io2, io3, io4, io5, io6, io7, io8) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) assert.Equal(t, 7, tuple.F7) assert.Equal(t, 8, tuple.F8) assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8}, order) } // Test SequenceParT8 func TestSequenceParT8(t *testing.T) { result := SequenceParT8(Of(1), Of(2), Of(3), Of(4), Of(5), Of(6), Of(7), Of(8)) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) assert.Equal(t, 7, tuple.F7) assert.Equal(t, 8, tuple.F8) } // Test SequenceTuple9 func TestSequenceTuple9(t *testing.T) { tup := T.MakeTuple9(Of(1), Of(2), Of(3), Of(4), Of(5), Of(6), Of(7), Of(8), Of(9)) result := SequenceTuple9(tup) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) assert.Equal(t, 7, tuple.F7) assert.Equal(t, 8, tuple.F8) assert.Equal(t, 9, tuple.F9) } // Test SequenceSeqT9 func TestSequenceSeqT9(t *testing.T) { var order []int io1 := func() int { order = append(order, 1); return 1 } io2 := func() int { order = append(order, 2); return 2 } io3 := func() int { order = append(order, 3); return 3 } io4 := func() int { order = append(order, 4); return 4 } io5 := func() int { order = append(order, 5); return 5 } io6 := func() int { order = append(order, 6); return 6 } io7 := func() int { order = append(order, 7); return 7 } io8 := func() int { order = append(order, 8); return 8 } io9 := func() int { order = append(order, 9); return 9 } result := SequenceSeqT9(io1, io2, io3, io4, io5, io6, io7, io8, io9) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) assert.Equal(t, 7, tuple.F7) assert.Equal(t, 8, tuple.F8) assert.Equal(t, 9, tuple.F9) assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9}, order) } // Test SequenceParT9 func TestSequenceParT9(t *testing.T) { result := SequenceParT9(Of(1), Of(2), Of(3), Of(4), Of(5), Of(6), Of(7), Of(8), Of(9)) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) assert.Equal(t, 7, tuple.F7) assert.Equal(t, 8, tuple.F8) assert.Equal(t, 9, tuple.F9) } // Test SequenceTuple10 func TestSequenceTuple10(t *testing.T) { tup := T.MakeTuple10(Of(1), Of(2), Of(3), Of(4), Of(5), Of(6), Of(7), Of(8), Of(9), Of(10)) result := SequenceTuple10(tup) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) assert.Equal(t, 7, tuple.F7) assert.Equal(t, 8, tuple.F8) assert.Equal(t, 9, tuple.F9) assert.Equal(t, 10, tuple.F10) } // Test SequenceSeqT10 func TestSequenceSeqT10(t *testing.T) { var order []int io1 := func() int { order = append(order, 1); return 1 } io2 := func() int { order = append(order, 2); return 2 } io3 := func() int { order = append(order, 3); return 3 } io4 := func() int { order = append(order, 4); return 4 } io5 := func() int { order = append(order, 5); return 5 } io6 := func() int { order = append(order, 6); return 6 } io7 := func() int { order = append(order, 7); return 7 } io8 := func() int { order = append(order, 8); return 8 } io9 := func() int { order = append(order, 9); return 9 } io10 := func() int { order = append(order, 10); return 10 } result := SequenceSeqT10(io1, io2, io3, io4, io5, io6, io7, io8, io9, io10) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) assert.Equal(t, 7, tuple.F7) assert.Equal(t, 8, tuple.F8) assert.Equal(t, 9, tuple.F9) assert.Equal(t, 10, tuple.F10) assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, order) } // Test SequenceParT10 func TestSequenceParT10(t *testing.T) { result := SequenceParT10(Of(1), Of(2), Of(3), Of(4), Of(5), Of(6), Of(7), Of(8), Of(9), Of(10)) tuple := result() assert.Equal(t, 1, tuple.F1) assert.Equal(t, 2, tuple.F2) assert.Equal(t, 3, tuple.F3) assert.Equal(t, 4, tuple.F4) assert.Equal(t, 5, tuple.F5) assert.Equal(t, 6, tuple.F6) assert.Equal(t, 7, tuple.F7) assert.Equal(t, 8, tuple.F8) assert.Equal(t, 9, tuple.F9) assert.Equal(t, 10, tuple.F10) }