predicate

package
v2.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 18, 2025 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package predicate provides functional programming utilities for working with predicates.

A predicate is a function that takes a value and returns a boolean, commonly used for filtering, validation, and conditional logic. This package offers combinators for composing predicates using logical operations (And, Or, Not), transforming predicates via ContraMap, and combining multiple predicates using Semigroup and Monoid abstractions.

Key features:

  • Boolean combinators: And, Or, Not
  • ContraMap for transforming predicates
  • Semigroup and Monoid instances for combining predicates

Example usage:

import P "github.com/IBM/fp-go/v2/predicate"

// Create predicates
isPositive := func(n int) bool { return n > 0 }
isEven := func(n int) bool { return n%2 == 0 }

// Combine predicates
isPositiveAndEven := F.Pipe1(isPositive, P.And(isEven))
isPositiveOrEven := F.Pipe1(isPositive, P.Or(isEven))
isNotPositive := P.Not(isPositive)

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Kleisli

type Kleisli[A, B any] = func(A) Predicate[B]

func IsEqual

func IsEqual[A any](pred eq.Eq[A]) Kleisli[A, A]

IsEqual creates a Kleisli arrow that tests if two values are equal using a custom equality function.

This function takes an Eq instance (which defines how to compare values of type A) and returns a curried function that can be used to create predicates for equality testing.

Parameters:

  • pred: An Eq[A] instance that defines equality for type A

Returns:

  • A Kleisli[A, A] that takes a value and returns a predicate testing equality with that value

Example:

type Person struct { Name string; Age int }
personEq := eq.MakeEq(func(a, b Person) bool {
    return a.Name == b.Name && a.Age == b.Age
})
isEqualToPerson := IsEqual(personEq)
alice := Person{Name: "Alice", Age: 30}
isAlice := isEqualToPerson(alice)
isAlice(Person{Name: "Alice", Age: 30}) // true
isAlice(Person{Name: "Bob", Age: 30})   // false

func IsStrictEqual

func IsStrictEqual[A comparable]() Kleisli[A, A]

IsStrictEqual creates a Kleisli arrow that tests if two values are equal using Go's == operator.

This is a convenience function for comparable types that uses strict equality (==) for comparison. It's equivalent to IsEqual with an Eq instance based on ==.

Returns:

  • A Kleisli[A, A] that takes a value and returns a predicate testing strict equality

Example:

isEqualTo5 := IsStrictEqual[int]()(5)
isEqualTo5(5)  // true
isEqualTo5(10) // false

isEqualToHello := IsStrictEqual[string]()("hello")
isEqualToHello("hello") // true
isEqualToHello("world") // false

type Monoid

type Monoid[A any] = monoid.Monoid[Predicate[A]]

Monoid represents a monoid instance for predicates, extending Semigroup with an identity element (empty predicate).

func MonoidAll

func MonoidAll[A any]() Monoid[A]

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 MonoidAny

func MonoidAny[A any]() Monoid[A]

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)

type Operator

type Operator[A, B any] = Kleisli[Predicate[A], B]

Operator represents a function that transforms a Predicate[A] into a Predicate[B]. This is useful for composing and transforming predicates.

func And

func And[A any](second Predicate[A]) Operator[A, A]

And creates an operator that combines two predicates using logical AND (&&).

The resulting predicate returns true only if both the first and second predicates return true. This function is curried, taking the second predicate first and returning an operator that takes the first predicate.

Example:

isPositive := func(n int) bool { return n > 0 }
isEven := func(n int) bool { return n%2 == 0 }
isPositiveAndEven := F.Pipe1(isPositive, And(isEven))
isPositiveAndEven(4)  // true
isPositiveAndEven(-2) // false
isPositiveAndEven(3)  // false
Example
package main

import (
	"fmt"

	F "github.com/IBM/fp-go/v2/function"
	"github.com/IBM/fp-go/v2/predicate"
)

func main() {
	isPositive := func(n int) bool { return n > 0 }
	isEven := func(n int) bool { return n%2 == 0 }
	isPositiveAndEven := F.Pipe1(isPositive, predicate.And(isEven))
	fmt.Println(isPositiveAndEven(4))
	fmt.Println(isPositiveAndEven(-2))
	fmt.Println(isPositiveAndEven(3))
}
Output:

true
false
false

func ContraMap

func ContraMap[A, B any](f func(B) A) Operator[A, B]

ContraMap creates a new predicate by transforming the input before applying an existing predicate.

This is a contravariant functor operation that allows you to adapt a predicate for type A to work with type B by providing a function that converts B to A. The resulting predicate first applies the mapping function f to transform the input, then applies the original predicate.

This is particularly useful when you have a predicate for one type and want to reuse it for a related type without rewriting the predicate logic.

Parameters:

  • f: A function that converts values of type B to type A

Returns:

  • An Operator that transforms a Predicate[A] into a Predicate[B]

Example:

type Person struct { Age int }
isAdult := func(age int) bool { return age >= 18 }
getAge := func(p Person) int { return p.Age }
isPersonAdult := F.Pipe1(isAdult, ContraMap(getAge))
isPersonAdult(Person{Age: 25}) // true
isPersonAdult(Person{Age: 15}) // false
Example
package main

import (
	"fmt"

	F "github.com/IBM/fp-go/v2/function"
	"github.com/IBM/fp-go/v2/predicate"
)

func main() {
	type Person struct{ Age int }
	isAdult := func(age int) bool { return age >= 18 }
	getAge := func(p Person) int { return p.Age }
	isPersonAdult := F.Pipe1(isAdult, predicate.ContraMap(getAge))
	fmt.Println(isPersonAdult(Person{Age: 25}))
	fmt.Println(isPersonAdult(Person{Age: 15}))
}
Output:

true
false

func Or

func Or[A any](second Predicate[A]) Operator[A, A]

Or creates an operator that combines two predicates using logical OR (||).

The resulting predicate returns true if either the first or second predicate returns true. This function is curried, taking the second predicate first and returning an operator that takes the first predicate.

Example:

isPositive := func(n int) bool { return n > 0 }
isEven := func(n int) bool { return n%2 == 0 }
isPositiveOrEven := F.Pipe1(isPositive, Or(isEven))
isPositiveOrEven(4)  // true
isPositiveOrEven(-2) // true
isPositiveOrEven(3)  // true
isPositiveOrEven(-3) // false
Example
package main

import (
	"fmt"

	F "github.com/IBM/fp-go/v2/function"
	"github.com/IBM/fp-go/v2/predicate"
)

func main() {
	isPositive := func(n int) bool { return n > 0 }
	isEven := func(n int) bool { return n%2 == 0 }
	isPositiveOrEven := F.Pipe1(isPositive, predicate.Or(isEven))
	fmt.Println(isPositiveOrEven(4))
	fmt.Println(isPositiveOrEven(-2))
	fmt.Println(isPositiveOrEven(3))
	fmt.Println(isPositiveOrEven(-3))
}
Output:

true
true
true
false

type Predicate

type Predicate[A any] = func(A) bool

Predicate represents a function that tests a value of type A and returns a boolean. It is commonly used for filtering, validation, and conditional logic.

func IsNonZero

func IsNonZero[A comparable]() Predicate[A]

IsNonZero creates a predicate that tests if a value is not equal to the zero value for its type.

This is the negation of IsZero, returning true for any non-zero value.

Returns:

  • A Predicate[A] that returns true if the value is not the zero value for type A

Example:

isNonZeroInt := IsNonZero[int]()
isNonZeroInt(0)  // false
isNonZeroInt(5)  // true
isNonZeroInt(-3) // true

isNonZeroString := IsNonZero[string]()
isNonZeroString("")      // false
isNonZeroString("hello") // true

isNonZeroPtr := IsNonZero[*int]()
isNonZeroPtr(nil)      // false
isNonZeroPtr(new(int)) // true

func IsZero

func IsZero[A comparable]() Predicate[A]

IsZero creates a predicate that tests if a value equals the zero value for its type.

The zero value is the default value for a type in Go (e.g., 0 for int, "" for string, false for bool, nil for pointers, etc.).

Returns:

  • A Predicate[A] that returns true if the value is the zero value for type A

Example:

isZeroInt := IsZero[int]()
isZeroInt(0)  // true
isZeroInt(5)  // false

isZeroString := IsZero[string]()
isZeroString("")      // true
isZeroString("hello") // false

isZeroBool := IsZero[bool]()
isZeroBool(false) // true
isZeroBool(true)  // false

func Not

func Not[A any](predicate Predicate[A]) Predicate[A]

Not negates a predicate, returning a new predicate that returns the opposite boolean value.

Given a predicate that returns true for some input, Not returns a predicate that returns false for the same input, and vice versa.

Example:

isPositive := func(n int) bool { return n > 0 }
isNotPositive := Not(isPositive)
isNotPositive(5)  // false
isNotPositive(-3) // true
Example
package main

import (
	"fmt"

	"github.com/IBM/fp-go/v2/predicate"
)

func main() {
	isPositive := func(n int) bool { return n > 0 }
	isNotPositive := predicate.Not(isPositive)
	fmt.Println(isNotPositive(5))
	fmt.Println(isNotPositive(-3))
}
Output:

false
true

type Semigroup

type Semigroup[A any] = semigroup.Semigroup[Predicate[A]]

Semigroup represents a semigroup instance for predicates, providing a way to combine two predicates into one using an associative operation.

func SemigroupAll

func SemigroupAll[A any]() Semigroup[A]

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 SemigroupAny

func SemigroupAny[A any]() Semigroup[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)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL