mirror of
https://github.com/IBM/fp-go.git
synced 2025-08-10 22:31:32 +02:00
fix: implement foldMap for records
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
This commit is contained in:
@@ -19,6 +19,7 @@ import (
|
||||
"sort"
|
||||
|
||||
F "github.com/IBM/fp-go/function"
|
||||
RAG "github.com/IBM/fp-go/internal/array"
|
||||
FC "github.com/IBM/fp-go/internal/functor"
|
||||
G "github.com/IBM/fp-go/internal/record"
|
||||
Mg "github.com/IBM/fp-go/magma"
|
||||
@@ -334,6 +335,62 @@ func ToEntries[M ~map[K]V, GT ~[]T.Tuple2[K, V], K comparable, V any](r M) GT {
|
||||
return ToArray[M, GT](r)
|
||||
}
|
||||
|
||||
// FromFoldableMap uses the reduce method for a higher kinded type to transform
|
||||
// its values into a tuple. The key and value are then used to populate the map. Duplicate
|
||||
// values are resolved via the provided [Mg.Magma]
|
||||
func FromFoldableMap[
|
||||
FCT ~func(A) T.Tuple2[K, V],
|
||||
HKTA any,
|
||||
FOLDABLE ~func(func(M, A) M, M) func(HKTA) M,
|
||||
M ~map[K]V,
|
||||
A any,
|
||||
K comparable,
|
||||
V any](m Mg.Magma[V], fld FOLDABLE) func(f FCT) func(fa HKTA) M {
|
||||
return func(f FCT) func(fa HKTA) M {
|
||||
return fld(func(dst M, a A) M {
|
||||
if IsEmpty(dst) {
|
||||
dst = make(M)
|
||||
}
|
||||
e := f(a)
|
||||
k := T.First(e)
|
||||
old, ok := dst[k]
|
||||
if ok {
|
||||
dst[k] = m.Concat(old, T.Second(e))
|
||||
} else {
|
||||
dst[k] = T.Second(e)
|
||||
}
|
||||
return dst
|
||||
}, Empty[M]())
|
||||
}
|
||||
}
|
||||
|
||||
func FromFoldable[
|
||||
HKTA any,
|
||||
FOLDABLE ~func(func(M, T.Tuple2[K, V]) M, M) func(HKTA) M,
|
||||
M ~map[K]V,
|
||||
K comparable,
|
||||
V any](m Mg.Magma[V], red FOLDABLE) func(fa HKTA) M {
|
||||
return FromFoldableMap[func(T.Tuple2[K, V]) T.Tuple2[K, V], HKTA, FOLDABLE](m, red)(F.Identity[T.Tuple2[K, V]])
|
||||
}
|
||||
|
||||
func FromArrayMap[
|
||||
FCT ~func(A) T.Tuple2[K, V],
|
||||
GA ~[]A,
|
||||
M ~map[K]V,
|
||||
A any,
|
||||
K comparable,
|
||||
V any](m Mg.Magma[V]) func(f FCT) func(fa GA) M {
|
||||
return FromFoldableMap[FCT](m, F.Bind23of3(RAG.Reduce[GA, A, M]))
|
||||
}
|
||||
|
||||
func FromArray[
|
||||
GA ~[]T.Tuple2[K, V],
|
||||
M ~map[K]V,
|
||||
K comparable,
|
||||
V any](m Mg.Magma[V]) func(fa GA) M {
|
||||
return FromFoldable[GA](m, F.Bind23of3(RAG.Reduce[GA, T.Tuple2[K, V], M]))
|
||||
}
|
||||
|
||||
func FromEntries[M ~map[K]V, GT ~[]T.Tuple2[K, V], K comparable, V any](fa GT) M {
|
||||
m := make(M)
|
||||
for _, t := range fa {
|
||||
|
@@ -16,6 +16,7 @@
|
||||
package record
|
||||
|
||||
import (
|
||||
EM "github.com/IBM/fp-go/endomorphism"
|
||||
Mg "github.com/IBM/fp-go/magma"
|
||||
Mo "github.com/IBM/fp-go/monoid"
|
||||
O "github.com/IBM/fp-go/option"
|
||||
@@ -291,6 +292,44 @@ func Copy[K comparable, V any](m map[K]V) map[K]V {
|
||||
}
|
||||
|
||||
// Clone creates a deep copy of the map using the provided endomorphism to clone the values
|
||||
func Clone[K comparable, V any](f func(V) V) func(m map[K]V) map[K]V {
|
||||
func Clone[K comparable, V any](f EM.Endomorphism[V]) EM.Endomorphism[map[K]V] {
|
||||
return G.Clone[map[K]V](f)
|
||||
}
|
||||
|
||||
// FromFoldableMap converts from a reducer to a map
|
||||
// Duplicate keys are resolved by the provided [Mg.Magma]
|
||||
func FromFoldableMap[
|
||||
FOLDABLE ~func(func(map[K]V, A) map[K]V, map[K]V) func(HKTA) map[K]V, // the reduce function
|
||||
A any,
|
||||
HKTA any,
|
||||
K comparable,
|
||||
V any](m Mg.Magma[V], red FOLDABLE) func(f func(A) T.Tuple2[K, V]) func(fa HKTA) map[K]V {
|
||||
return G.FromFoldableMap[func(A) T.Tuple2[K, V]](m, red)
|
||||
}
|
||||
|
||||
// FromArrayMap converts from an array to a map
|
||||
// Duplicate keys are resolved by the provided [Mg.Magma]
|
||||
func FromArrayMap[
|
||||
A any,
|
||||
K comparable,
|
||||
V any](m Mg.Magma[V]) func(f func(A) T.Tuple2[K, V]) func(fa []A) map[K]V {
|
||||
return G.FromArrayMap[func(A) T.Tuple2[K, V], []A, map[K]V](m)
|
||||
}
|
||||
|
||||
// FromFoldable converts from a reducer to a map
|
||||
// Duplicate keys are resolved by the provided [Mg.Magma]
|
||||
func FromFoldable[
|
||||
HKTA any,
|
||||
FOLDABLE ~func(func(map[K]V, T.Tuple2[K, V]) map[K]V, map[K]V) func(HKTA) map[K]V, // the reduce function
|
||||
K comparable,
|
||||
V any](m Mg.Magma[V], red FOLDABLE) func(fa HKTA) map[K]V {
|
||||
return G.FromFoldable[HKTA, FOLDABLE](m, red)
|
||||
}
|
||||
|
||||
// FromArray converts from an array to a map
|
||||
// Duplicate keys are resolved by the provided [Mg.Magma]
|
||||
func FromArray[
|
||||
K comparable,
|
||||
V any](m Mg.Magma[V]) func(fa []T.Tuple2[K, V]) map[K]V {
|
||||
return G.FromArray[[]T.Tuple2[K, V], map[K]V](m)
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2023 IBM Corp.
|
||||
// All rights reserved.
|
||||
// Copyright (c) 2023 IBM Corp.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -23,8 +23,10 @@ import (
|
||||
|
||||
A "github.com/IBM/fp-go/array"
|
||||
"github.com/IBM/fp-go/internal/utils"
|
||||
Mg "github.com/IBM/fp-go/magma"
|
||||
O "github.com/IBM/fp-go/option"
|
||||
S "github.com/IBM/fp-go/string"
|
||||
T "github.com/IBM/fp-go/tuple"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -149,3 +151,28 @@ func TestCopyVsClone(t *testing.T) {
|
||||
assert.NotEqual(t, cpy, cln)
|
||||
assert.Equal(t, src, cpy)
|
||||
}
|
||||
|
||||
func TestFromArrayMap(t *testing.T) {
|
||||
src1 := A.From("a", "b", "c", "a")
|
||||
frm := FromArrayMap[string, string](Mg.Second[string]())
|
||||
|
||||
f := frm(T.Replicate2[string])
|
||||
|
||||
res1 := f(src1)
|
||||
|
||||
assert.Equal(t, map[string]string{
|
||||
"a": "a",
|
||||
"b": "b",
|
||||
"c": "c",
|
||||
}, res1)
|
||||
|
||||
src2 := A.From("A", "B", "C", "A")
|
||||
|
||||
res2 := f(src2)
|
||||
|
||||
assert.Equal(t, map[string]string{
|
||||
"A": "A",
|
||||
"B": "B",
|
||||
"C": "C",
|
||||
}, res2)
|
||||
}
|
||||
|
Reference in New Issue
Block a user