package iter import ( F "github.com/IBM/fp-go/v2/function" M "github.com/IBM/fp-go/v2/monoid" ) func MonadReduceWithIndex[GA ~func(yield func(A) bool), A, B any](fa GA, f func(int, B, A) B, initial B) B { current := initial var i int for a := range fa { current = f(i, current, a) i += 1 } return current } func MonadReduce[GA ~func(yield func(A) bool), A, B any](fa GA, f func(B, A) B, initial B) B { current := initial for a := range fa { current = f(current, a) } return current } // Concat concatenates two sequences, yielding all elements from left followed by all elements from right. func Concat[GT ~func(yield func(T) bool), T any](left, right GT) GT { return func(yield func(T) bool) { for t := range left { if !yield(t) { return } } for t := range right { if !yield(t) { return } } } } func Of[GA ~func(yield func(A) bool), A any](a A) GA { return func(yield func(A) bool) { yield(a) } } func MonadAppend[GA ~func(yield func(A) bool), A any](f GA, tail A) GA { return Concat(f, Of[GA](tail)) } func Append[GA ~func(yield func(A) bool), A any](tail A) func(GA) GA { return F.Bind2nd(Concat[GA], Of[GA](tail)) } func Prepend[GA ~func(yield func(A) bool), A any](head A) func(GA) GA { return F.Bind1st(Concat[GA], Of[GA](head)) } func Empty[GA ~func(yield func(A) bool), A any]() GA { return func(_ func(A) bool) {} } func ToArray[GA ~func(yield func(A) bool), GB ~[]A, A any](fa GA) GB { bs := make(GB, 0) for a := range fa { bs = append(bs, a) } return bs } func MonadMapToArray[GA ~func(yield func(A) bool), GB ~[]B, A, B any](fa GA, f func(A) B) GB { bs := make(GB, 0) for a := range fa { bs = append(bs, f(a)) } return bs } func MapToArray[GA ~func(yield func(A) bool), GB ~[]B, A, B any](f func(A) B) func(GA) GB { return F.Bind2nd(MonadMapToArray[GA, GB], f) } func MonadMapToArrayWithIndex[GA ~func(yield func(A) bool), GB ~[]B, A, B any](fa GA, f func(int, A) B) GB { bs := make(GB, 0) var i int for a := range fa { bs = append(bs, f(i, a)) i += 1 } return bs } func MapToArrayWithIndex[GA ~func(yield func(A) bool), GB ~[]B, A, B any](f func(int, A) B) func(GA) GB { return F.Bind2nd(MonadMapToArrayWithIndex[GA, GB], f) } func Monoid[GA ~func(yield func(A) bool), A any]() M.Monoid[GA] { return M.MakeMonoid(Concat[GA], Empty[GA]()) }