fn: add FindIdx function

This commit is contained in:
Keagan McClelland 2024-04-15 15:34:05 -06:00
parent 5902aa5159
commit c3603ccf96
No known key found for this signature in database
GPG Key ID: FA7E65C951F12439
2 changed files with 48 additions and 2 deletions

View File

@ -53,7 +53,7 @@ func Map[A, B any](f func(A) B, s []A) []B {
// Filter creates a new slice of values where all the members of the returned // Filter creates a new slice of values where all the members of the returned
// slice pass the predicate that is supplied in the argument. // slice pass the predicate that is supplied in the argument.
func Filter[A any](pred func(A) bool, s []A) []A { func Filter[A any](pred Pred[A], s []A) []A {
res := make([]A, 0) res := make([]A, 0)
for _, val := range s { for _, val := range s {
@ -92,7 +92,7 @@ func Foldr[A, B any](f func(A, B) B, seed B, s []A) B {
// Find returns the first value that passes the supplied predicate, or None if // Find returns the first value that passes the supplied predicate, or None if
// the value wasn't found. // the value wasn't found.
func Find[A any](pred func(A) bool, s []A) Option[A] { func Find[A any](pred Pred[A], s []A) Option[A] {
for _, val := range s { for _, val := range s {
if pred(val) { if pred(val) {
return Some(val) return Some(val)
@ -102,6 +102,18 @@ func Find[A any](pred func(A) bool, s []A) Option[A] {
return None[A]() return None[A]()
} }
// FindIdx returns the first value that passes the supplied predicate along with
// its index in the slice. If no satisfactory value is found, None is returned.
func FindIdx[A any](pred Pred[A], s []A) Option[T2[int, A]] {
for i, val := range s {
if pred(val) {
return Some(NewT2[int, A](i, val))
}
}
return None[T2[int, A]]()
}
// Flatten takes a slice of slices and returns a concatenation of those slices. // Flatten takes a slice of slices and returns a concatenation of those slices.
func Flatten[A any](s [][]A) []A { func Flatten[A any](s [][]A) []A {
sz := Foldr( sz := Foldr(

View File

@ -340,3 +340,37 @@ func TestPropForEachConcOutperformsMapWhenExpensive(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
} }
func TestPropFindIdxFindIdentity(t *testing.T) {
f := func(div, mod uint8, s []uint8) bool {
if div == 0 || div == 1 {
return true
}
pred := func(i uint8) bool {
return i%div == mod
}
foundIdx := FindIdx(pred, s)
// onlyVal :: Option[T2[A, B]] -> Option[B]
onlyVal := MapOption(func(t2 T2[int, uint8]) uint8 {
return t2.Second()
})
valuesEqual := Find(pred, s) == onlyVal(foundIdx)
idxGetsVal := ElimOption(
foundIdx,
func() bool { return true },
func(t2 T2[int, uint8]) bool {
return s[t2.First()] == t2.Second()
})
return valuesEqual && idxGetsVal
}
if err := quick.Check(f, nil); err != nil {
t.Fatal(err)
}
}