Add functional predicate NAND (#182)

Add new function, NAND, designed to create a composed predicate representing the logical NAND operation
applied to a list of predicates. The NAND operation is a logical operation
that returns true only if all perdicate result in false otherwise false
This commit is contained in:
donutloop
2024-02-26 02:58:19 +01:00
committed by GitHub
parent a43bc554ee
commit 805e2543d0
3 changed files with 54 additions and 4 deletions

View File

@@ -16,6 +16,22 @@ func And[T any](predicates ...func(T) bool) func(T) bool {
}
}
// And returns a composed predicate that represents the logical NAND of a list of predicates.
// It evaluates to true only if all predicates evaluate to false for the given value.
func Nand[T any](predicates ...func(T) bool) func(T) bool {
if len(predicates) < 2 {
panic("programming error: predicates count must be at least 2")
}
return func(value T) bool {
for _, predicate := range predicates {
if predicate(value) {
return false // Short-circuit on the first true predicate
}
}
return true // True if all predicates are false
}
}
// Negate returns a predicate that represents the logical negation of this predicate.
func Negate[T any](predicate func(T) bool) func(T) bool {
return func(value T) bool {

View File

@@ -53,6 +53,22 @@ func ExampleAnd() {
// false
}
func ExampleNand() {
isNumericAndLength5 := Nand(
func(s string) bool { return strings.ContainsAny(s, "0123456789") },
func(s string) bool { return len(s) == 5 },
)
fmt.Println(isNumericAndLength5("12345"))
fmt.Println(isNumericAndLength5("1234"))
fmt.Println(isNumericAndLength5("abcdef"))
// Output:
// false
// false
// true
}
func ExampleNor() {
match := Nor(
func(s string) bool { return strings.ContainsAny(s, "0123456789") },

View File

@@ -54,6 +54,21 @@ func TestPredicatesAndPure(t *testing.T) {
assert.ShouldBeFalse(isNumericAndLength5("abcde"))
}
func TestPredicatesNandPure(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestPredicatesNandPure")
isNumericAndLength5 := Nand(
func(s string) bool { return strings.ContainsAny(s, "0123456789") },
func(s string) bool { return len(s) == 5 },
)
assert.ShouldBeFalse(isNumericAndLength5("12345"))
assert.ShouldBeFalse(isNumericAndLength5("1234"))
assert.ShouldBeTrue(isNumericAndLength5("abcdef"))
}
func TestPredicatesNorPure(t *testing.T) {
t.Parallel()
@@ -108,9 +123,12 @@ func TestPredicatesMix(t *testing.T) {
assert.ShouldBeFalse(c("hello!"))
c = Nor(a, b)
assert.ShouldBeFalse(c("hello!"))
k := Nor(a, b)
assert.ShouldBeFalse(k("hello!"))
c = Xnor(a, b)
assert.ShouldBeTrue(c("hello!"))
o := Xnor(a, b)
assert.ShouldBeTrue(o("hello!"))
p := Nand(c, k)
assert.ShouldBeTrue(p("hello!"))
}