Skip to content

Commit 03debd3

Browse files
authored
Merge pull request #39 from IBM/cleue-implement-compact
fix: add compact methods
2 parents cf1c886 + 4f04344 commit 03debd3

File tree

7 files changed

+116
-1
lines changed

7 files changed

+116
-1
lines changed

either/array.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,15 @@ func SequenceArrayG[GA ~[]A, GOA ~[]Either[E, A], E, A any](ma GOA) Either[E, GA
4444
func SequenceArray[E, A any](ma []Either[E, A]) Either[E, []A] {
4545
return SequenceArrayG[[]A](ma)
4646
}
47+
48+
// CompactArrayG discards the none values and keeps the some values
49+
func CompactArrayG[A1 ~[]Either[E, A], A2 ~[]A, E, A any](fa A1) A2 {
50+
return RA.Reduce(fa, func(out A2, value Either[E, A]) A2 {
51+
return MonadFold(value, F.Constant1[E](out), F.Bind1st(RA.Append[A2, A], out))
52+
}, make(A2, len(fa)))
53+
}
54+
55+
// CompactArray discards the none values and keeps the some values
56+
func CompactArray[E, A any](fa []Either[E, A]) []A {
57+
return CompactArrayG[[]Either[E, A], []A](fa)
58+
}

either/record.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,24 @@ func SequenceRecordG[GA ~map[K]A, GOA ~map[K]Either[E, A], K comparable, E, A an
4343
func SequenceRecord[K comparable, E, A any](ma map[K]Either[E, A]) Either[E, map[K]A] {
4444
return SequenceRecordG[map[K]A](ma)
4545
}
46+
47+
func upsertAtReadWrite[M ~map[K]V, K comparable, V any](r M, k K, v V) M {
48+
r[k] = v
49+
return r
50+
}
51+
52+
// CompactRecordG discards the noe values and keeps the some values
53+
func CompactRecordG[M1 ~map[K]Either[E, A], M2 ~map[K]A, K comparable, E, A any](m M1) M2 {
54+
out := make(M2)
55+
onLeft := F.Constant1[E](out)
56+
return RR.ReduceWithIndex(m, func(key K, _ M2, value Either[E, A]) M2 {
57+
return MonadFold(value, onLeft, func(v A) M2 {
58+
return upsertAtReadWrite(out, key, v)
59+
})
60+
}, out)
61+
}
62+
63+
// CompactRecord discards all none values and keeps the somes
64+
func CompactRecord[K comparable, E, A any](m map[K]Either[E, A]) map[K]A {
65+
return CompactRecordG[map[K]Either[E, A], map[K]A](m)
66+
}

either/record_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) 2023 IBM Corp.
2+
// All rights reserved.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
package either
17+
18+
import (
19+
"testing"
20+
21+
"github.com/stretchr/testify/assert"
22+
)
23+
24+
func TestCompactRecord(t *testing.T) {
25+
// make the map
26+
m := make(map[string]Either[string, int])
27+
m["foo"] = Left[int]("error")
28+
m["bar"] = Right[string](1)
29+
// compact it
30+
m1 := CompactRecord(m)
31+
// check expected
32+
exp := map[string]int{
33+
"bar": 1,
34+
}
35+
36+
assert.Equal(t, exp, m1)
37+
}

option/array.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,15 @@ func SequenceArrayG[GA ~[]A, GOA ~[]Option[A], A any](ma GOA) Option[GA] {
4444
func SequenceArray[A any](ma []Option[A]) Option[[]A] {
4545
return SequenceArrayG[[]A](ma)
4646
}
47+
48+
// CompactArrayG discards the none values and keeps the some values
49+
func CompactArrayG[A1 ~[]Option[A], A2 ~[]A, A any](fa A1) A2 {
50+
return RA.Reduce(fa, func(out A2, value Option[A]) A2 {
51+
return MonadFold(value, F.Constant(out), F.Bind1st(RA.Append[A2, A], out))
52+
}, make(A2, len(fa)))
53+
}
54+
55+
// CompactArray discards the none values and keeps the some values
56+
func CompactArray[A any](fa []Option[A]) []A {
57+
return CompactArrayG[[]Option[A], []A](fa)
58+
}

option/record.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,21 @@ func SequenceRecordG[GA ~map[K]A, GOA ~map[K]Option[A], K comparable, A any](ma
4444
func SequenceRecord[K comparable, A any](ma map[K]Option[A]) Option[map[K]A] {
4545
return SequenceRecordG[map[K]A](ma)
4646
}
47+
48+
func upsertAtReadWrite[M ~map[K]V, K comparable, V any](r M, k K, v V) M {
49+
r[k] = v
50+
return r
51+
}
52+
53+
// CompactRecordG discards the noe values and keeps the some values
54+
func CompactRecordG[M1 ~map[K]Option[A], M2 ~map[K]A, K comparable, A any](m M1) M2 {
55+
bnd := F.Bind12of3(upsertAtReadWrite[M2])
56+
return RR.ReduceWithIndex(m, func(key K, m M2, value Option[A]) M2 {
57+
return MonadFold(value, F.Constant(m), bnd(m, key))
58+
}, make(M2))
59+
}
60+
61+
// CompactRecord discards the noe values and keeps the some values
62+
func CompactRecord[K comparable, A any](m map[K]Option[A]) map[K]A {
63+
return CompactRecordG[map[K]Option[A], map[K]A](m)
64+
}

option/record_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,18 @@ func TestSequenceRecord(t *testing.T) {
3030
"b": Of("B"),
3131
}))
3232
}
33+
34+
func TestCompactRecord(t *testing.T) {
35+
// make the map
36+
m := make(map[string]Option[int])
37+
m["foo"] = None[int]()
38+
m["bar"] = Some(1)
39+
// compact it
40+
m1 := CompactRecord(m)
41+
// check expected
42+
exp := map[string]int{
43+
"bar": 1,
44+
}
45+
46+
assert.Equal(t, exp, m1)
47+
}

option/testing/laws.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import (
2323
O "github.com/IBM/fp-go/option"
2424
)
2525

26-
// AssertLaws asserts the apply monad laws for the `Either` monad
26+
// AssertLaws asserts the apply monad laws for the [Option] monad
2727
func AssertLaws[A, B, C any](t *testing.T,
2828
eqa EQ.Eq[A],
2929
eqb EQ.Eq[B],

0 commit comments

Comments
 (0)