Skip to content

Commit

Permalink
iter, parallel: Improve some more generics decls (#4)
Browse files Browse the repository at this point in the history
* Improve some more generics decls.

* Improve generics decls in the parallel package.

* Missed some tildes.
  • Loading branch information
bobg authored Mar 19, 2023
1 parent e341ea5 commit 9091c40
Show file tree
Hide file tree
Showing 9 changed files with 17 additions and 15 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ require (
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
)

retract v2.0.0
4 changes: 2 additions & 2 deletions iter/accum.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ package iter
// and
//
// out[i+1] == f(out[i], inp[i+1])
func Accum[T any](inp Of[T], f func(T, T) T) Of[T] {
func Accum[F ~func(T, T) T, T any](inp Of[T], f F) Of[T] {
return Accumx(inp, func(a, b T) (T, error) {
return f(a, b), nil
})
Expand All @@ -27,7 +27,7 @@ func Accum[T any](inp Of[T], f func(T, T) T) Of[T] {
// and
//
// out[i+1] == f(out[i], inp[i+1])
func Accumx[T any](inp Of[T], f func(T, T) (T, error)) Of[T] {
func Accumx[F ~func(T, T) (T, error), T any](inp Of[T], f F) Of[T] {
return &accumIter[T]{
inp: inp,
f: f,
Expand Down
2 changes: 1 addition & 1 deletion iter/chan.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func toChan[T any](ctx context.Context, inp Of[T]) (<-chan T, func() error) {
// The function receives a channel for producing values.
// The channel closes when the function exits.
// Any error produced by the function is the value of the iterator's Err method.
func Go[T any](f func(ch chan<- T) error) Of[T] {
func Go[F ~func(chan<- T) error, T any](f F) Of[T] {
var (
ch = make(chan T)
res = &chanIter[T]{ch: ch}
Expand Down
4 changes: 2 additions & 2 deletions iter/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package iter

// Filter copies the input iterator to the output,
// including only those elements that cause f to return true.
func Filter[T any](inp Of[T], f func(T) bool) Of[T] {
func Filter[F ~func(T) bool, T any](inp Of[T], f F) Of[T] {
return &filterIter[T]{inp: inp, f: f}
}

Expand Down Expand Up @@ -34,7 +34,7 @@ func (f *filterIter[T]) Err() error {
// discarding the initial elements until the first one that causes f to return true.
// That element and the remaining elements of inp are included in the output,
// and f is not called again.
func SkipUntil[T any](inp Of[T], f func(T) bool) Of[T] {
func SkipUntil[F ~func(T) bool, T any](inp Of[T], f F) Of[T] {
skipping := true
return Filter(inp, func(val T) bool {
if !skipping {
Expand Down
2 changes: 1 addition & 1 deletion iter/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
// iteration stops and the error is available via the iterator's Err method.
// Otherwise, each call to f should return a value and a true boolean.
// When f returns a false boolean, it signals the normal end of iteration.
func Gen[T any](f func() (T, bool, error)) Of[T] {
func Gen[F ~func() (T, bool, error), T any](f F) Of[T] {
return &genIter[T]{f: f}
}

Expand Down
4 changes: 2 additions & 2 deletions iter/gomap.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ func (*goMapIter[K, V]) Err() error {
}

// FromMap produces an iterator of key-value pairs from a Go map.
func FromMap[K comparable, V any](m map[K]V) Of[Pair[K, V]] {
func FromMap[M ~map[K]V, K comparable, V any](m M) Of[Pair[K, V]] {
return &goMapIter[K, V]{
m: m,
keysIter: FromMapKeys(m),
}
}

// FromMapKeys produces an iterator over the keys of a Go map.
func FromMapKeys[K comparable, V any](m map[K]V) Of[K] {
func FromMapKeys[M ~map[K]V, K comparable, V any](m M) Of[K] {
keys := make([]K, 0, len(m))
for k := range m {
keys = append(keys, k)
Expand Down
4 changes: 2 additions & 2 deletions iter/map.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package iter

// Map produces an iterator of values transformed from an input iterator by a simple mapping function.
func Map[T, U any](inp Of[T], f func(T) U) Of[U] {
func Map[F ~func(T) U, T, U any](inp Of[T], f F) Of[U] {
return Mapx(inp, func(val T) (U, error) {
return f(val), nil
})
Expand All @@ -11,7 +11,7 @@ func Map[T, U any](inp Of[T], f func(T) U) Of[U] {
// It produces an iterator of values transformed from an input iterator by a mapping function.
// If the mapping function returns an error,
// iteration stops and the error is available via the output iterator's Err method.
func Mapx[T, U any](inp Of[T], f func(T) (U, error)) Of[U] {
func Mapx[F ~func(T) (U, error), T, U any](inp Of[T], f F) Of[U] {
return &mapIter[T, U]{inp: inp, f: f}
}

Expand Down
2 changes: 1 addition & 1 deletion iter/page.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ package iter
//
// The slice in every non-final call of the callback is guaranteed to have a length of pageSize.
// The final call of the callback may contain an empty slice.
func Page[T any](inp Of[T], pageSize int, f func([]T, bool) error) error {
func Page[F ~func(S, bool) error, S ~[]T, T any](inp Of[T], pageSize int, f F) error {
page := make([]T, 0, pageSize)
for inp.Next() {
page = append(page, inp.Val())
Expand Down
8 changes: 4 additions & 4 deletions parallel/parallel.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (e Error) Unwrap() error {
//
// The resulting slice has length n.
// The value at position i comes from worker i.
func Values[T any](ctx context.Context, n int, f func(context.Context, int) (T, error)) ([]T, error) {
func Values[F ~func(context.Context, int) (T, error), T any](ctx context.Context, n int, f F) ([]T, error) {
g, ctx := errgroup.WithContext(ctx)
result := make([]T, n)

Expand Down Expand Up @@ -69,7 +69,7 @@ func Values[T any](ctx context.Context, n int, f func(context.Context, int) (T,
// An error from any worker cancels them all.
//
// The caller gets an iterator over the values produced.
func Producers[T any](ctx context.Context, n int, f func(context.Context, int, func(T) error) error) iter.Of[T] {
func Producers[F ~func(context.Context, int, func(T) error) error, T any](ctx context.Context, n int, f F) iter.Of[T] {
ch := make(chan T)
g, innerCtx := errgroup.WithContext(ctx)

Expand Down Expand Up @@ -117,7 +117,7 @@ func Producers[T any](ctx context.Context, n int, f func(context.Context, int, f
// After any error, the value-sending callback will return an error.
// (Not the original error, however.
// For that, the caller should still invoke the close callback.)
func Consumers[T any](ctx context.Context, n int, f func(context.Context, int, T) error) (func(T) error, func() error) {
func Consumers[F ~func(context.Context, int, T) error, T any](ctx context.Context, n int, f F) (func(T) error, func() error) {
ch := make(chan T, n)

g, ctx := errgroup.WithContext(ctx)
Expand Down Expand Up @@ -167,7 +167,7 @@ func Consumers[T any](ctx context.Context, n int, f func(context.Context, int, T
//
// Each call of the callback is synchronous.
// Any desired concurrency is the responsibility of the caller.
func Pool[T, U any](n int, f func(T) (U, error)) func(T) (U, error) {
func Pool[F ~func(T) (U, error), T, U any](n int, f F) func(T) (U, error) {
var (
running int
mu sync.Mutex
Expand Down

0 comments on commit 9091c40

Please sign in to comment.