func Waterfall(ctx context.Context, f Funcs, options ...Option) (<-chan FuncResult, error) {
	fns, err := f.funcs()
	if err != nil {
		return nil, err
	}
	opts := newOptions(options...)
	fnc := make(chan FuncResult, 1)
	go func() {
		defer close(fnc)
		var (
			fn  function
			err error
		)
		args := paramsValues(opts.args)
		for _, fn = range fns {
			select {
			case <-ctx.Done():
				fnc <- FuncResult{err: internal.NewContextError(ctx)}
				return
			default:
			}
			if args, err = execFunc(ctx, fn.Value, args); err != nil {
				break
			}
		}
		sendResult(fnc, fn.ID, args, err)
	}()
	return fnc, nil
}
Waterfall executes all the functions in sequence, each function return value is passed to the next function.
If the last or only return value of a function is of type error, this value is not passed to the next function.

If the first parameter of any function is of type context.Context, the ctx passed to Waterfall will be used
as the first argument of such functions, unless a previous function returns a context as its first return value,
in such cases the returned context will be used instead.

The returned channel will receive either the last function return values or an error, if any.
The execution flow stops in case a function last or only return value evaluates to a non-nil error.

options is an optional list of Option for configuring Waterfall execution. Waterfall will use the given
WithArgs values as the arguments of the first function.
package async
import (
	"context"
	"fmt"
	"reflect"
	"sync"
	"sync/atomic"
	"github.com/rdleal/go-async/async/internal"
)
type function struct {
	ID    interface{}
	Value reflect.Value
}
type Funcs []interface{}
func (f Funcs) funcs() ([]function, error) {
	var fns []function
	for i, fn := range f {
		v := reflect.ValueOf(fn)
		if !isFunc(v) {
			return nil, fmt.Errorf("%w at #%d: %v", ErrInvalidFunc, i, v)
		}
		fns = append(fns, function{i, v})
	}
	return fns, nil
}
type FuncMap map[string]interface{}
func (fm FuncMap) funcs() ([]function, error) {
	var fns []function
	for k, fn := range fm {
		v := reflect.ValueOf(fn)
		if !isFunc(v) {
			return nil, fmt.Errorf("%w for key %q: %v", ErrInvalidFunc, k, v)
		}
		fns = append(fns, function{k, v})
	}
	return fns, nil
}
func isFunc(v reflect.Value) bool {
	return v.Kind() == reflect.Func
}
type FuncResult struct {
	id   interface{}
	vals Values
	err  error
}
func (f FuncResult) Index() (i int, ok bool) {
	i, ok = f.id.(int)
	return
}
func (f FuncResult) Name() (name string, ok bool) {
	name, ok = f.id.(string)
	return
}
func (f FuncResult) Returned() (Values, error) {
	return f.vals, f.err
}