github.com/kazu/loncha@v0.6.3/currying.go (about)

     1  package loncha
     2  
     3  import (
     4  	"golang.org/x/exp/constraints"
     5  )
     6  
     7  type curryParam[T any] struct {
     8  	Default T
     9  }
    10  
    11  // OptCurry ... functional option
    12  type OptCurry[T any] func(*curryParam[T]) OptCurry[T]
    13  
    14  func Default[T any](t T) OptCurry[T] {
    15  
    16  	return func(p *curryParam[T]) OptCurry[T] {
    17  		prev := p.Default
    18  		p.Default = t
    19  		return Default(prev)
    20  	}
    21  }
    22  
    23  func (p *curryParam[T]) Options(opts ...OptCurry[T]) (prevs []OptCurry[T]) {
    24  
    25  	for _, opt := range opts {
    26  		prevs = append(prevs, opt(p))
    27  	}
    28  	return
    29  }
    30  
    31  func NewOpt[T any](opts ...OptCurry[T]) *curryParam[T] {
    32  
    33  	p := curryParam[T]{}
    34  	p.Options(opts...)
    35  	return &p
    36  }
    37  
    38  // FilterFunc ... function  generated by Filterlize()
    39  type FilterFunc[T any] func([]T) []T
    40  
    41  type GetFunc[T any] func([]T) T
    42  
    43  // Filterable ... generate filter function for slice
    44  func Filterable[T any](fns ...CondFunc2[T]) FilterFunc[T] {
    45  	return innerfilterlable(true, fns...)
    46  }
    47  
    48  // Deletable ... generate deleting function by fns Condition for slice
    49  func Deletable[T comparable](fns ...CondFunc2[T]) FilterFunc[T] {
    50  	return innerfilterlable(false, fns...)
    51  }
    52  
    53  // Selectable ... generate deleting function by fns Condition for slice
    54  func Selectable[T any](fns ...CondFunc2[T]) FilterFunc[T] {
    55  	return Filterable(fns...)
    56  }
    57  
    58  // Gettable	 ... generate deleting function by fns Condition for slice
    59  func Gettable[T any](fns ...CondFunc2[T]) GetFunc[T] {
    60  	return func(datas []T) T {
    61  		result := Filterable(fns...)(datas)
    62  		if len(result) > 0 {
    63  			return result[0]
    64  		}
    65  		return *new(T)
    66  	}
    67  }
    68  
    69  func innerfilterlable[T any](keep bool, fns ...CondFunc2[T]) FilterFunc[T] {
    70  	return func(srcs []T) (dsts []T) {
    71  		dsts = srcs
    72  		innerFilter2(&dsts, keep, fns...)
    73  		return
    74  	}
    75  }
    76  
    77  // InjecterFunc ... condition function for Injectable
    78  type InjecterFunc[T any, R any] func([]T) R
    79  
    80  // Injectable ... generate Inject functions
    81  func Injectable[T any, V any](injectFn InjectFn[T, V], opts ...OptCurry[V]) InjecterFunc[T, V] {
    82  
    83  	return func(src []T) (result V) {
    84  		return Inject(src, injectFn, opts...)
    85  	}
    86  }
    87  
    88  // Reducable ... alias of Injectable
    89  func Reducable[T any, V any](injectFn InjectFn[T, V], opts ...OptCurry[V]) InjecterFunc[T, V] {
    90  	return Injectable(injectFn, opts...)
    91  }
    92  
    93  // Containable ... generate function of slice contain.
    94  func Containable[T comparable](fn CondFunc2[T]) func([]T) bool {
    95  
    96  	return func(srcs []T) bool {
    97  		for _, src := range srcs {
    98  			if fn(&src) {
    99  				return true
   100  			}
   101  		}
   102  		return false
   103  	}
   104  }
   105  
   106  // Every ... Determines whether all the members of an array satisfy the specified test.
   107  func Every[T any](fn CondFunc2[T]) func(...T) bool {
   108  
   109  	return func(srcs ...T) bool {
   110  		result := true
   111  		for _, src := range srcs {
   112  			if result && !fn(&src) {
   113  				result = false
   114  			}
   115  		}
   116  		return result
   117  	}
   118  }
   119  
   120  // EveryWithIndex ... Determines whether all the members of an array satisfy the specified test.
   121  func EveryWithIndex[T comparable](fn CondFuncWithIndex[T]) func(...T) bool {
   122  
   123  	return func(srcs ...T) bool {
   124  		result := true
   125  		for i, src := range srcs {
   126  			if result && !fn(i, &src) {
   127  				result = false
   128  			}
   129  		}
   130  		return result
   131  	}
   132  }
   133  
   134  // Convertable ...  generate function of slice conversion.
   135  func Convertable[S, D any](fn ConvFunc[S, D]) func([]S) []D {
   136  	return func(srcs []S) (dsts []D) {
   137  		dsts = []D{}
   138  
   139  		for _, src := range srcs {
   140  			if d, removed := fn(src); !removed {
   141  				dsts = append(dsts, d)
   142  			}
   143  		}
   144  		return
   145  	}
   146  }
   147  
   148  // Number ... Number constraints
   149  type Number interface {
   150  	constraints.Integer | constraints.Float
   151  }
   152  
   153  func max[T Number](s T, d T) T {
   154  
   155  	if s < d {
   156  		return d
   157  	}
   158  	return s
   159  }
   160  
   161  func min[T Number](s T, d T) T {
   162  	return -max(-s, -d)
   163  }
   164  
   165  // Zipper ...  return tuple operation result using fn  with double slice,
   166  func Zipper[T, S, R any](fn func(R, T, S) R, start R) func([]T, []S) R {
   167  
   168  	return func(tlist []T, slist []S) (result R) {
   169  
   170  		result = start
   171  		for i := range tlist[:min(len(tlist), len(slist))] {
   172  			result = fn(result, tlist[i], slist[i])
   173  		}
   174  		return
   175  	}
   176  
   177  }
   178  
   179  // ToMap ... function for Zipper . return map from double array.
   180  func ToMap[K, V constraints.Ordered](r map[K]V, k K, v V) map[K]V {
   181  
   182  	r[k] = v
   183  	return r
   184  
   185  }