Skip to content

Commit 7991c2f

Browse files
committed
adding predicate combinators
1 parent b76019f commit 7991c2f

File tree

1 file changed

+96
-18
lines changed

1 file changed

+96
-18
lines changed

core/src/main/java/fj/function/Booleans.java

Lines changed: 96 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package fj.function;
22

3-
import fj.F;
4-
import fj.F2;
5-
import fj.F3;
3+
64
import static fj.Function.*;
75

6+
import fj.F;
87
import fj.Monoid;
8+
import fj.Semigroup;
99
import fj.data.List;
1010
import fj.data.Stream;
1111

@@ -42,20 +42,12 @@ private Booleans() {
4242
/**
4343
* Logical negation.
4444
*/
45-
public static final F<Boolean, Boolean> not = new F<Boolean, Boolean>() {
46-
public Boolean f(final Boolean p) {
47-
return !p;
48-
}
49-
};
45+
public static final F<Boolean, Boolean> not = p -> !p;
5046

5147
/**
5248
* Curried form of logical "only if" (material implication).
5349
*/
54-
public static final F<Boolean, F<Boolean, Boolean>> implies = curry(new F2<Boolean, Boolean, Boolean>() {
55-
public Boolean f(final Boolean p, final Boolean q) {
56-
return !p || q;
57-
}
58-
});
50+
public static final F<Boolean, F<Boolean, Boolean>> implies = curry((p, q) -> !p || q);
5951

6052
/**
6153
* Curried form of logical "if" (reverse material implication).
@@ -92,6 +84,56 @@ public static boolean and(final List<Boolean> l) {
9284
return Monoid.conjunctionMonoid.sumLeft(l);
9385
}
9486

87+
/**
88+
* maps function on given predicate function
89+
* @param p predicate to be mapped over
90+
* @param f function
91+
* @return predicate function
92+
*/
93+
public static <A, B> F<B, Boolean> contramap(F<B, A> f, F<A, Boolean> p){
94+
return compose(p, f);
95+
}
96+
97+
/**
98+
* checks if given predicate does not hold for given function
99+
* @param p predicate to be mapped over
100+
* @param f function
101+
* @return predicate function
102+
*/
103+
public static <A, B> F<B, Boolean> isnot(F<B, A> f, F<A, Boolean> p){
104+
return compose(not, contramap(f, p));
105+
}
106+
107+
/**
108+
* composes given predicates using conjunction
109+
* @param p1 first predicate
110+
* @param p2 second predicate
111+
* @return composed predicate function
112+
*/
113+
public static <A> F<A, Boolean> and(F<A, Boolean> p1, F<A, Boolean> p2){
114+
return Semigroup.<A, Boolean>functionSemigroup(conjunctionSemigroup).sum(p1, p2);
115+
}
116+
117+
/**
118+
* composes given predicates using exclusive disjunction
119+
* @param p1 first predicate
120+
* @param p2 second predicate
121+
* @return composed predicate function
122+
*/
123+
public static <A> F<A, Boolean> xor(F<A, Boolean> p1, F<A, Boolean> p2){
124+
return Semigroup.<A, Boolean>functionSemigroup(exclusiveDisjunctionSemiGroup).sum(p1, p2);
125+
}
126+
127+
/**
128+
* returns composes given predicates using disjunction
129+
* @param p1 first predicate
130+
* @param p2 second predicate
131+
* @return composed predicate function
132+
*/
133+
public static <A> F<A, Boolean> or(F<A, Boolean> p1, F<A, Boolean> p2){
134+
return Semigroup.<A, Boolean>functionSemigroup(disjunctionSemigroup).sum(p1, p2);
135+
}
136+
95137
/**
96138
* Returns true if all the elements of the given stream are true.
97139
*
@@ -102,6 +144,46 @@ public static boolean and(final Stream<Boolean> l) {
102144
return Monoid.conjunctionMonoid.sumLeft(l);
103145
}
104146

147+
/**
148+
* Returns a composed predicate of given Stream of predicates
149+
*
150+
* @param l A stream of predicate functions
151+
* @return composed predicate function
152+
*/
153+
public static <A> F<A, Boolean> andAll(final Stream<F<A, Boolean>> l) {
154+
return Monoid.<A, Boolean>functionMonoid(Monoid.conjunctionMonoid).sumLeft(l);
155+
}
156+
157+
/**
158+
* Returns a composed predicate of given List of predicates
159+
*
160+
* @param l A list of predicate functions
161+
* @return composed predicate function
162+
*/
163+
public static <A> F<A, Boolean> andAll(final List<F<A, Boolean>> l) {
164+
return Monoid.<A, Boolean>functionMonoid(Monoid.conjunctionMonoid).sumLeft(l);
165+
}
166+
167+
/**
168+
* Returns a composed predicate of given List of predicates
169+
*
170+
* @param l A list of predicate functions
171+
* @return composed predicate function
172+
*/
173+
public static <A> F<A, Boolean> orAll(final List<F<A, Boolean>> l) {
174+
return Monoid.<A, Boolean>functionMonoid(Monoid.disjunctionMonoid).sumLeft(l);
175+
}
176+
177+
/**
178+
* Returns a composed predicate of given Stream of predicates
179+
*
180+
* @param l A stream of predicate functions
181+
* @return composed predicate function
182+
*/
183+
public static <A> F<A, Boolean> orAll(final Stream<F<A, Boolean>> l) {
184+
return Monoid.<A, Boolean>functionMonoid(Monoid.disjunctionMonoid).sumLeft(l);
185+
}
186+
105187
/**
106188
* Returns true if any element of the given list is true.
107189
*
@@ -139,10 +221,6 @@ public static <A> F<A, Boolean> not(final F<A, Boolean> p) {
139221
* @return A function that returns its second argument if the first argument is true, otherwise the third argument.
140222
*/
141223
public static <A> F<Boolean, F<A, F<A, A>>> cond() {
142-
return curry(new F3<Boolean, A, A, A>() {
143-
public A f(final Boolean p, final A a1, final A a2) {
144-
return p ? a1 : a2;
145-
}
146-
});
224+
return curry((p, a1, a2) -> p ? a1 : a2);
147225
}
148226
}

0 commit comments

Comments
 (0)