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 }