mirror of
https://github.com/IBM/fp-go.git
synced 2025-11-23 22:14:53 +02:00
fix: implement FoldMap
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
This commit is contained in:
@@ -294,3 +294,13 @@ func SliceRight[A any](start int) func([]A) []A {
|
|||||||
func Copy[A any](b []A) []A {
|
func Copy[A any](b []A) []A {
|
||||||
return G.Copy(b)
|
return G.Copy(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FoldMap maps and folds an array. Map the Array passing each value to the iterating function. Then fold the results using the provided Monoid.
|
||||||
|
func FoldMap[A, B any](m M.Monoid[B]) func(func(A) B) func([]A) B {
|
||||||
|
return G.FoldMap[[]A](m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fold folds the array using the provided Monoid.
|
||||||
|
func Fold[A any](m M.Monoid[A]) func([]A) A {
|
||||||
|
return G.Fold[[]A](m)
|
||||||
|
}
|
||||||
|
|||||||
@@ -173,3 +173,22 @@ func TestFilterMap(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(t, From("a1", "a3"), res)
|
assert.Equal(t, From("a1", "a3"), res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFoldMap(t *testing.T) {
|
||||||
|
src := From("a", "b", "c")
|
||||||
|
|
||||||
|
fold := FoldMap[string](S.Monoid)(strings.ToUpper)
|
||||||
|
|
||||||
|
assert.Equal(t, "ABC", fold(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleFoldMap() {
|
||||||
|
src := From("a", "b", "c")
|
||||||
|
|
||||||
|
fold := FoldMap[string](S.Monoid)(strings.ToUpper)
|
||||||
|
|
||||||
|
fmt.Println(fold(src))
|
||||||
|
|
||||||
|
// Output: ABC
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package generic
|
|||||||
import (
|
import (
|
||||||
F "github.com/IBM/fp-go/function"
|
F "github.com/IBM/fp-go/function"
|
||||||
"github.com/IBM/fp-go/internal/array"
|
"github.com/IBM/fp-go/internal/array"
|
||||||
|
M "github.com/IBM/fp-go/monoid"
|
||||||
O "github.com/IBM/fp-go/option"
|
O "github.com/IBM/fp-go/option"
|
||||||
"github.com/IBM/fp-go/tuple"
|
"github.com/IBM/fp-go/tuple"
|
||||||
)
|
)
|
||||||
@@ -209,3 +210,19 @@ func Copy[AS ~[]A, A any](b AS) AS {
|
|||||||
copy(buf, b)
|
copy(buf, b)
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FoldMap[AS ~[]A, A, B any](m M.Monoid[B]) func(func(A) B) func(AS) B {
|
||||||
|
return func(f func(A) B) func(AS) B {
|
||||||
|
return func(as AS) B {
|
||||||
|
return array.Reduce(as, func(cur B, a A) B {
|
||||||
|
return m.Concat(cur, f(a))
|
||||||
|
}, m.Empty())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fold[AS ~[]A, A any](m M.Monoid[A]) func(AS) A {
|
||||||
|
return func(as AS) A {
|
||||||
|
return array.Reduce(as, m.Concat, m.Empty())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,11 +18,17 @@ package generic
|
|||||||
import (
|
import (
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
O "github.com/IBM/fp-go/ord"
|
O "github.com/IBM/fp-go/ord"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Sort implements a stable sort on the array given the provided ordering
|
// Sort implements a stable sort on the array given the provided ordering
|
||||||
func Sort[GA ~[]T, T any](ord O.Ord[T]) func(ma GA) GA {
|
func Sort[GA ~[]T, T any](ord O.Ord[T]) func(ma GA) GA {
|
||||||
|
return SortByKey[GA](ord, F.Identity[T])
|
||||||
|
}
|
||||||
|
|
||||||
|
// SortByKey implements a stable sort on the array given the provided ordering on an extracted key
|
||||||
|
func SortByKey[GA ~[]T, K, T any](ord O.Ord[K], f func(T) K) func(ma GA) GA {
|
||||||
|
|
||||||
return func(ma GA) GA {
|
return func(ma GA) GA {
|
||||||
// nothing to sort
|
// nothing to sort
|
||||||
@@ -34,7 +40,7 @@ func Sort[GA ~[]T, T any](ord O.Ord[T]) func(ma GA) GA {
|
|||||||
cpy := make(GA, l)
|
cpy := make(GA, l)
|
||||||
copy(cpy, ma)
|
copy(cpy, ma)
|
||||||
sort.Slice(cpy, func(i, j int) bool {
|
sort.Slice(cpy, func(i, j int) bool {
|
||||||
return ord.Compare(cpy[i], cpy[j]) < 0
|
return ord.Compare(f(cpy[i]), f(cpy[j])) < 0
|
||||||
})
|
})
|
||||||
return cpy
|
return cpy
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,3 +24,8 @@ import (
|
|||||||
func Sort[T any](ord O.Ord[T]) func(ma []T) []T {
|
func Sort[T any](ord O.Ord[T]) func(ma []T) []T {
|
||||||
return G.Sort[[]T](ord)
|
return G.Sort[[]T](ord)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SortByKey implements a stable sort on the array given the provided ordering on an extracted key
|
||||||
|
func SortByKey[K, T any](ord O.Ord[K], f func(T) K) func(ma []T) []T {
|
||||||
|
return G.SortByKey[[]T](ord, f)
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import (
|
|||||||
F "github.com/IBM/fp-go/function"
|
F "github.com/IBM/fp-go/function"
|
||||||
"github.com/IBM/fp-go/internal/utils"
|
"github.com/IBM/fp-go/internal/utils"
|
||||||
IO "github.com/IBM/fp-go/iooption/generic"
|
IO "github.com/IBM/fp-go/iooption/generic"
|
||||||
|
M "github.com/IBM/fp-go/monoid"
|
||||||
N "github.com/IBM/fp-go/number"
|
N "github.com/IBM/fp-go/number"
|
||||||
O "github.com/IBM/fp-go/option"
|
O "github.com/IBM/fp-go/option"
|
||||||
T "github.com/IBM/fp-go/tuple"
|
T "github.com/IBM/fp-go/tuple"
|
||||||
@@ -226,3 +227,15 @@ func FilterChain[GVV ~func() O.Option[T.Tuple2[GVV, GV]], GV ~func() O.Option[T.
|
|||||||
Flatten[GVV],
|
Flatten[GVV],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FoldMap[GU ~func() O.Option[T.Tuple2[GU, U]], FCT ~func(U) V, U, V any](m M.Monoid[V]) func(FCT) func(ma GU) V {
|
||||||
|
return func(f FCT) func(ma GU) V {
|
||||||
|
return Reduce[GU](func(cur V, a U) V {
|
||||||
|
return m.Concat(cur, f(a))
|
||||||
|
}, m.Empty())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fold[GU ~func() O.Option[T.Tuple2[GU, U]], U any](m M.Monoid[U]) func(ma GU) U {
|
||||||
|
return Reduce[GU](m.Concat, m.Empty())
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package stateless
|
|||||||
import (
|
import (
|
||||||
G "github.com/IBM/fp-go/iterator/stateless/generic"
|
G "github.com/IBM/fp-go/iterator/stateless/generic"
|
||||||
L "github.com/IBM/fp-go/lazy"
|
L "github.com/IBM/fp-go/lazy"
|
||||||
|
M "github.com/IBM/fp-go/monoid"
|
||||||
O "github.com/IBM/fp-go/option"
|
O "github.com/IBM/fp-go/option"
|
||||||
T "github.com/IBM/fp-go/tuple"
|
T "github.com/IBM/fp-go/tuple"
|
||||||
)
|
)
|
||||||
@@ -123,3 +124,13 @@ func Count(start int) Iterator[int] {
|
|||||||
func FilterChain[U, V any](f func(U) O.Option[Iterator[V]]) func(ma Iterator[U]) Iterator[V] {
|
func FilterChain[U, V any](f func(U) O.Option[Iterator[V]]) func(ma Iterator[U]) Iterator[V] {
|
||||||
return G.FilterChain[Iterator[Iterator[V]], Iterator[V], Iterator[U]](f)
|
return G.FilterChain[Iterator[Iterator[V]], Iterator[V], Iterator[U]](f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FoldMap maps and folds an iterator. Map the iterator passing each value to the iterating function. Then fold the results using the provided Monoid.
|
||||||
|
func FoldMap[U, V any](m M.Monoid[V]) func(func(U) V) func(ma Iterator[U]) V {
|
||||||
|
return G.FoldMap[Iterator[U], func(U) V, U, V](m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fold folds the iterator using the provided Monoid.
|
||||||
|
func Fold[U any](m M.Monoid[U]) func(Iterator[U]) U {
|
||||||
|
return G.Fold[Iterator[U]](m)
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,12 +18,14 @@ package stateless
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
A "github.com/IBM/fp-go/array"
|
A "github.com/IBM/fp-go/array"
|
||||||
F "github.com/IBM/fp-go/function"
|
F "github.com/IBM/fp-go/function"
|
||||||
"github.com/IBM/fp-go/internal/utils"
|
"github.com/IBM/fp-go/internal/utils"
|
||||||
O "github.com/IBM/fp-go/option"
|
O "github.com/IBM/fp-go/option"
|
||||||
|
S "github.com/IBM/fp-go/string"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -102,3 +104,14 @@ func TestAp(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(t, A.From("a-1-c", "a-1-d", "a-2-c", "a-2-d", "b-1-c", "b-1-d", "b-2-c", "b-2-d"), it)
|
assert.Equal(t, A.From("a-1-c", "a-1-d", "a-2-c", "a-2-d", "b-1-c", "b-1-d", "b-2-c", "b-2-d"), it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleFoldMap() {
|
||||||
|
src := From("a", "b", "c")
|
||||||
|
|
||||||
|
fold := FoldMap[string](S.Monoid)(strings.ToUpper)
|
||||||
|
|
||||||
|
fmt.Println(fold(src))
|
||||||
|
|
||||||
|
// Output: ABC
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,11 +16,14 @@
|
|||||||
package generic
|
package generic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sort"
|
||||||
|
|
||||||
F "github.com/IBM/fp-go/function"
|
F "github.com/IBM/fp-go/function"
|
||||||
G "github.com/IBM/fp-go/internal/record"
|
G "github.com/IBM/fp-go/internal/record"
|
||||||
Mg "github.com/IBM/fp-go/magma"
|
Mg "github.com/IBM/fp-go/magma"
|
||||||
Mo "github.com/IBM/fp-go/monoid"
|
Mo "github.com/IBM/fp-go/monoid"
|
||||||
O "github.com/IBM/fp-go/option"
|
O "github.com/IBM/fp-go/option"
|
||||||
|
"github.com/IBM/fp-go/ord"
|
||||||
T "github.com/IBM/fp-go/tuple"
|
T "github.com/IBM/fp-go/tuple"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -40,6 +43,46 @@ func Values[M ~map[K]V, GV ~[]V, K comparable, V any](r M) GV {
|
|||||||
return collect[M, GV](r, F.Second[K, V])
|
return collect[M, GV](r, F.Second[K, V])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func KeysOrd[M ~map[K]V, GK ~[]K, K comparable, V any](o ord.Ord[K]) func(r M) GK {
|
||||||
|
return func(r M) GK {
|
||||||
|
return collectOrd[M, GK](o, r, F.First[K, V])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValuesOrd[M ~map[K]V, GV ~[]V, K comparable, V any](o ord.Ord[K]) func(r M) GV {
|
||||||
|
return func(r M) GV {
|
||||||
|
return collectOrd[M, GV](o, r, F.Second[K, V])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func collectOrd[M ~map[K]V, GR ~[]R, K comparable, V, R any](o ord.Ord[K], r M, f func(K, V) R) GR {
|
||||||
|
// create the entries
|
||||||
|
entries := toEntriesOrd[M, []T.Tuple2[K, V]](o, r)
|
||||||
|
// collect this array
|
||||||
|
ft := T.Tupled2(f)
|
||||||
|
count := len(entries)
|
||||||
|
result := make(GR, count)
|
||||||
|
for i := count - 1; i >= 0; i-- {
|
||||||
|
result[i] = ft(entries[i])
|
||||||
|
}
|
||||||
|
// done
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func reduceOrd[M ~map[K]V, K comparable, V, R any](o ord.Ord[K], r M, f func(K, R, V) R, initial R) R {
|
||||||
|
// create the entries
|
||||||
|
entries := toEntriesOrd[M, []T.Tuple2[K, V]](o, r)
|
||||||
|
// collect this array
|
||||||
|
current := initial
|
||||||
|
count := len(entries)
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
t := entries[i]
|
||||||
|
current = f(T.First(t), current, T.Second(t))
|
||||||
|
}
|
||||||
|
// done
|
||||||
|
return current
|
||||||
|
}
|
||||||
|
|
||||||
func collect[M ~map[K]V, GR ~[]R, K comparable, V, R any](r M, f func(K, V) R) GR {
|
func collect[M ~map[K]V, GR ~[]R, K comparable, V, R any](r M, f func(K, V) R) GR {
|
||||||
count := len(r)
|
count := len(r)
|
||||||
result := make(GR, count)
|
result := make(GR, count)
|
||||||
@@ -250,6 +293,27 @@ func ToArray[M ~map[K]V, GT ~[]T.Tuple2[K, V], K comparable, V any](r M) GT {
|
|||||||
return collect[M, GT](r, T.MakeTuple2[K, V])
|
return collect[M, GT](r, T.MakeTuple2[K, V])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func toEntriesOrd[M ~map[K]V, GT ~[]T.Tuple2[K, V], K comparable, V any](o ord.Ord[K], r M) GT {
|
||||||
|
// total number of elements
|
||||||
|
count := len(r)
|
||||||
|
// produce an array that we can sort by key
|
||||||
|
entries := make(GT, count)
|
||||||
|
idx := 0
|
||||||
|
for k, v := range r {
|
||||||
|
entries[idx] = T.MakeTuple2(k, v)
|
||||||
|
idx++
|
||||||
|
}
|
||||||
|
sort.Slice(entries, func(i, j int) bool {
|
||||||
|
return o.Compare(T.First(entries[i]), T.First(entries[j])) < 0
|
||||||
|
})
|
||||||
|
// final entries
|
||||||
|
return entries
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToEntriesOrd[M ~map[K]V, GT ~[]T.Tuple2[K, V], K comparable, V any](o ord.Ord[K]) func(r M) GT {
|
||||||
|
return F.Bind1st(toEntriesOrd[M, GT, K, V], o)
|
||||||
|
}
|
||||||
|
|
||||||
func ToEntries[M ~map[K]V, GT ~[]T.Tuple2[K, V], K comparable, V any](r M) GT {
|
func ToEntries[M ~map[K]V, GT ~[]T.Tuple2[K, V], K comparable, V any](r M) GT {
|
||||||
return ToArray[M, GT](r)
|
return ToArray[M, GT](r)
|
||||||
}
|
}
|
||||||
@@ -379,3 +443,67 @@ func IsNonNil[M ~map[K]V, K comparable, V any](m M) bool {
|
|||||||
func ConstNil[M ~map[K]V, K comparable, V any]() M {
|
func ConstNil[M ~map[K]V, K comparable, V any]() M {
|
||||||
return (M)(nil)
|
return (M)(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FoldMap[AS ~map[K]A, K comparable, A, B any](m Mo.Monoid[B]) func(func(A) B) func(AS) B {
|
||||||
|
return func(f func(A) B) func(AS) B {
|
||||||
|
return Reduce[AS](func(cur B, a A) B {
|
||||||
|
return m.Concat(cur, f(a))
|
||||||
|
}, m.Empty())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fold[AS ~map[K]A, K comparable, A any](m Mo.Monoid[A]) func(AS) A {
|
||||||
|
return Reduce[AS](m.Concat, m.Empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
func FoldMapWithIndex[AS ~map[K]A, K comparable, A, B any](m Mo.Monoid[B]) func(func(K, A) B) func(AS) B {
|
||||||
|
return func(f func(K, A) B) func(AS) B {
|
||||||
|
return ReduceWithIndex[AS](func(k K, cur B, a A) B {
|
||||||
|
return m.Concat(cur, f(k, a))
|
||||||
|
}, m.Empty())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReduceOrdWithIndex[M ~map[K]V, K comparable, V, R any](o ord.Ord[K]) func(func(K, R, V) R, R) func(M) R {
|
||||||
|
return func(f func(K, R, V) R, initial R) func(M) R {
|
||||||
|
return func(m M) R {
|
||||||
|
return reduceOrd(o, m, f, initial)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReduceOrd[M ~map[K]V, K comparable, V, R any](o ord.Ord[K]) func(func(R, V) R, R) func(M) R {
|
||||||
|
ro := ReduceOrdWithIndex[M, K, V, R](o)
|
||||||
|
return func(f func(R, V) R, initial R) func(M) R {
|
||||||
|
return ro(F.Ignore1of3[K](f), initial)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func FoldMapOrd[AS ~map[K]A, K comparable, A, B any](o ord.Ord[K]) func(m Mo.Monoid[B]) func(func(A) B) func(AS) B {
|
||||||
|
red := ReduceOrd[AS, K, A, B](o)
|
||||||
|
return func(m Mo.Monoid[B]) func(func(A) B) func(AS) B {
|
||||||
|
return func(f func(A) B) func(AS) B {
|
||||||
|
return red(func(cur B, a A) B {
|
||||||
|
return m.Concat(cur, f(a))
|
||||||
|
}, m.Empty())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func FoldOrd[AS ~map[K]A, K comparable, A any](o ord.Ord[K]) func(m Mo.Monoid[A]) func(AS) A {
|
||||||
|
red := ReduceOrd[AS, K, A, A](o)
|
||||||
|
return func(m Mo.Monoid[A]) func(AS) A {
|
||||||
|
return red(m.Concat, m.Empty())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func FoldMapOrdWithIndex[AS ~map[K]A, K comparable, A, B any](o ord.Ord[K]) func(m Mo.Monoid[B]) func(func(K, A) B) func(AS) B {
|
||||||
|
red := ReduceOrdWithIndex[AS, K, A, B](o)
|
||||||
|
return func(m Mo.Monoid[B]) func(func(K, A) B) func(AS) B {
|
||||||
|
return func(f func(K, A) B) func(AS) B {
|
||||||
|
return red(func(k K, cur B, a A) B {
|
||||||
|
return m.Concat(cur, f(k, a))
|
||||||
|
}, m.Empty())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import (
|
|||||||
Mg "github.com/IBM/fp-go/magma"
|
Mg "github.com/IBM/fp-go/magma"
|
||||||
Mo "github.com/IBM/fp-go/monoid"
|
Mo "github.com/IBM/fp-go/monoid"
|
||||||
O "github.com/IBM/fp-go/option"
|
O "github.com/IBM/fp-go/option"
|
||||||
|
"github.com/IBM/fp-go/ord"
|
||||||
G "github.com/IBM/fp-go/record/generic"
|
G "github.com/IBM/fp-go/record/generic"
|
||||||
T "github.com/IBM/fp-go/tuple"
|
T "github.com/IBM/fp-go/tuple"
|
||||||
)
|
)
|
||||||
@@ -215,3 +216,53 @@ func FilterChainWithIndex[V1 any, K comparable, V2 any](m Mo.Monoid[map[K]V2]) f
|
|||||||
func FilterChain[V1 any, K comparable, V2 any](m Mo.Monoid[map[K]V2]) func(func(V1) O.Option[map[K]V2]) func(map[K]V1) map[K]V2 {
|
func FilterChain[V1 any, K comparable, V2 any](m Mo.Monoid[map[K]V2]) func(func(V1) O.Option[map[K]V2]) func(map[K]V1) map[K]V2 {
|
||||||
return G.FilterChain[map[K]V1](m)
|
return G.FilterChain[map[K]V1](m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FoldMap maps and folds a record. Map the record passing each value to the iterating function. Then fold the results using the provided Monoid.
|
||||||
|
func FoldMap[K comparable, A, B any](m Mo.Monoid[B]) func(func(A) B) func(map[K]A) B {
|
||||||
|
return G.FoldMap[map[K]A](m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FoldMapWithIndex maps and folds a record. Map the record passing each value to the iterating function. Then fold the results using the provided Monoid.
|
||||||
|
func FoldMapWithIndex[K comparable, A, B any](m Mo.Monoid[B]) func(func(K, A) B) func(map[K]A) B {
|
||||||
|
return G.FoldMapWithIndex[map[K]A](m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fold folds the record using the provided Monoid.
|
||||||
|
func Fold[K comparable, A any](m Mo.Monoid[A]) func(map[K]A) A {
|
||||||
|
return G.Fold[map[K]A](m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReduceOrdWithIndex reduces a map into a single value via a reducer function making sure that the keys are passed to the reducer in the specified order
|
||||||
|
func ReduceOrdWithIndex[V, R any, K comparable](o ord.Ord[K]) func(func(K, R, V) R, R) func(map[K]V) R {
|
||||||
|
return G.ReduceOrdWithIndex[map[K]V, K, V, R](o)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReduceOrd reduces a map into a single value via a reducer function making sure that the keys are passed to the reducer in the specified order
|
||||||
|
func ReduceOrd[V, R any, K comparable](o ord.Ord[K]) func(func(R, V) R, R) func(map[K]V) R {
|
||||||
|
return G.ReduceOrd[map[K]V, K, V, R](o)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FoldMap maps and folds a record. Map the record passing each value to the iterating function. Then fold the results using the provided Monoid and the items in the provided order
|
||||||
|
func FoldMapOrd[A, B any, K comparable](o ord.Ord[K]) func(m Mo.Monoid[B]) func(func(A) B) func(map[K]A) B {
|
||||||
|
return G.FoldMapOrd[map[K]A, K, A, B](o)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fold folds the record using the provided Monoid with the items passed in the given order
|
||||||
|
func FoldOrd[A any, K comparable](o ord.Ord[K]) func(m Mo.Monoid[A]) func(map[K]A) A {
|
||||||
|
return G.FoldOrd[map[K]A, K, A](o)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FoldMapWithIndex maps and folds a record. Map the record passing each value to the iterating function. Then fold the results using the provided Monoid and the items in the provided order
|
||||||
|
func FoldMapOrdWithIndex[K comparable, A, B any](o ord.Ord[K]) func(m Mo.Monoid[B]) func(func(K, A) B) func(map[K]A) B {
|
||||||
|
return G.FoldMapOrdWithIndex[map[K]A, K, A, B](o)
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeysOrd returns the keys in the map in their given order
|
||||||
|
func KeysOrd[V any, K comparable](o ord.Ord[K]) func(r map[K]V) []K {
|
||||||
|
return G.KeysOrd[map[K]V, []K, K, V](o)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValuesOrd returns the values in the map ordered by their keys in the given order
|
||||||
|
func ValuesOrd[V any, K comparable](o ord.Ord[K]) func(r map[K]V) []V {
|
||||||
|
return G.ValuesOrd[map[K]V, []V, K, V](o)
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,10 +18,12 @@ package record
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/IBM/fp-go/internal/utils"
|
"github.com/IBM/fp-go/internal/utils"
|
||||||
O "github.com/IBM/fp-go/option"
|
O "github.com/IBM/fp-go/option"
|
||||||
|
S "github.com/IBM/fp-go/string"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -99,3 +101,33 @@ func TestFilterChain(t *testing.T) {
|
|||||||
"c": "c3",
|
"c": "c3",
|
||||||
}, res)
|
}, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleFoldMap() {
|
||||||
|
src := map[string]string{
|
||||||
|
"a": "a",
|
||||||
|
"b": "b",
|
||||||
|
"c": "c",
|
||||||
|
}
|
||||||
|
|
||||||
|
fold := FoldMap[string, string](S.Monoid)(strings.ToUpper)
|
||||||
|
|
||||||
|
fmt.Println(fold(src))
|
||||||
|
|
||||||
|
// Output: ABC
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleValuesOrd() {
|
||||||
|
src := map[string]string{
|
||||||
|
"c": "a",
|
||||||
|
"b": "b",
|
||||||
|
"a": "c",
|
||||||
|
}
|
||||||
|
|
||||||
|
getValues := ValuesOrd[string](S.Ord)
|
||||||
|
|
||||||
|
fmt.Println(getValues(src))
|
||||||
|
|
||||||
|
// Output: [c b a]
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user