1
0
mirror of https://github.com/IBM/fp-go.git synced 2025-11-25 22:21:49 +02:00
Files
fp-go/v2/predicate/monoid.go
Carsten Leue 3385c705dc Implement v2 using type aliases (#141)
* fix: initial checkin of v2

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: slowly migrate IO

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: migrate MonadTraverseArray and TraverseArray

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: migrate traversal

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: complete migration of IO

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: migrate ioeither

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: refactorY

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: next step in migration

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: adjust IO generation code

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: get rid of more IO methods

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: get rid of more IO

* fix: convert iooption

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: convert reader

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: convert a bit of reader

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: new build script

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: cleanup

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: reformat

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: simplify

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: some cleanup

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: adjust Pair to Haskell semantic

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: documentation and testcases

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: some performance optimizations

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: remove coverage

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: better doc

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

---------

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
2025-11-06 09:27:00 +01:00

145 lines
4.8 KiB
Go

// Copyright (c) 2023 - 2025 IBM Corp.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package predicate
import (
F "github.com/IBM/fp-go/v2/function"
"github.com/IBM/fp-go/v2/monoid"
"github.com/IBM/fp-go/v2/semigroup"
)
type (
// Semigroup represents a semigroup instance for predicates, providing a way to combine
// two predicates into one using an associative operation.
Semigroup[A any] = semigroup.Semigroup[Predicate[A]]
// Monoid represents a monoid instance for predicates, extending Semigroup with an
// identity element (empty predicate).
Monoid[A any] = monoid.Monoid[Predicate[A]]
)
// SemigroupAny creates a semigroup that combines predicates using logical OR (||).
//
// When two predicates are combined with this semigroup, the resulting predicate returns
// true if either of the original predicates returns true. This implements the associative
// operation for disjunction.
//
// Returns:
// - A Semigroup[A] that combines predicates with OR logic
//
// Example:
//
// s := SemigroupAny[int]()
// isPositive := func(n int) bool { return n > 0 }
// isEven := func(n int) bool { return n%2 == 0 }
// isPositiveOrEven := s.Concat(isPositive, isEven)
// isPositiveOrEven(4) // true (even)
// isPositiveOrEven(3) // true (positive)
// isPositiveOrEven(-2) // true (even)
// isPositiveOrEven(-3) // false (neither)
func SemigroupAny[A any]() Semigroup[A] {
return semigroup.MakeSemigroup(func(first Predicate[A], second Predicate[A]) Predicate[A] {
return F.Pipe1(
first,
Or(second),
)
})
}
// SemigroupAll creates a semigroup that combines predicates using logical AND (&&).
//
// When two predicates are combined with this semigroup, the resulting predicate returns
// true only if both of the original predicates return true. This implements the associative
// operation for conjunction.
//
// Returns:
// - A Semigroup[A] that combines predicates with AND logic
//
// Example:
//
// s := SemigroupAll[int]()
// isPositive := func(n int) bool { return n > 0 }
// isEven := func(n int) bool { return n%2 == 0 }
// isPositiveAndEven := s.Concat(isPositive, isEven)
// isPositiveAndEven(4) // true (both)
// isPositiveAndEven(3) // false (not even)
// isPositiveAndEven(-2) // false (not positive)
// isPositiveAndEven(-3) // false (neither)
func SemigroupAll[A any]() Semigroup[A] {
return semigroup.MakeSemigroup(func(first Predicate[A], second Predicate[A]) Predicate[A] {
return F.Pipe1(
first,
And(second),
)
})
}
// MonoidAny creates a monoid that combines predicates using logical OR (||).
//
// This extends SemigroupAny with an identity element: a predicate that always returns false.
// The identity element satisfies the property that combining it with any predicate p yields p.
// This is useful for folding/reducing a collection of predicates where an empty collection
// should result in a predicate that always returns false.
//
// Returns:
// - A Monoid[A] that combines predicates with OR logic and has false as identity
//
// Example:
//
// m := MonoidAny[int]()
// predicates := []Predicate[int]{
// func(n int) bool { return n > 10 },
// func(n int) bool { return n < 0 },
// }
// combined := A.Reduce(m.Empty(), m.Concat)(predicates)
// combined(15) // true (> 10)
// combined(-5) // true (< 0)
// combined(5) // false (neither)
func MonoidAny[A any]() Monoid[A] {
return monoid.MakeMonoid(
SemigroupAny[A]().Concat,
F.Constant1[A](false),
)
}
// MonoidAll creates a monoid that combines predicates using logical AND (&&).
//
// This extends SemigroupAll with an identity element: a predicate that always returns true.
// The identity element satisfies the property that combining it with any predicate p yields p.
// This is useful for folding/reducing a collection of predicates where an empty collection
// should result in a predicate that always returns true.
//
// Returns:
// - A Monoid[A] that combines predicates with AND logic and has true as identity
//
// Example:
//
// m := MonoidAll[int]()
// predicates := []Predicate[int]{
// func(n int) bool { return n > 0 },
// func(n int) bool { return n < 100 },
// }
// combined := A.Reduce(m.Empty(), m.Concat)(predicates)
// combined(50) // true (both conditions)
// combined(-5) // false (not > 0)
// combined(150) // false (not < 100)
func MonoidAll[A any]() Monoid[A] {
return monoid.MakeMonoid(
SemigroupAll[A]().Concat,
F.Constant1[A](true),
)
}