001 package fj.function; 002 003 import fj.F; 004 import fj.F2; 005 import fj.F3; 006 import static fj.Function.*; 007 import fj.data.List; 008 import fj.data.Stream; 009 import fj.pre.Monoid; 010 import static fj.pre.Semigroup.disjunctionSemigroup; 011 import static fj.pre.Semigroup.conjunctionSemigroup; 012 import static fj.pre.Semigroup.exclusiveDisjunctionSemiGroup; 013 014 /** 015 * Curried logical functions. 016 * 017 * @version %build.number%<br> 018 * <ul> 019 * <li>$LastChangedRevision: 143 $</li> 020 * <li>$LastChangedDate: 2009-05-22 03:56:25 +1000 (Fri, 22 May 2009) $</li> 021 * </ul> 022 */ 023 public final class Booleans { 024 private Booleans() { 025 throw new UnsupportedOperationException(); 026 } 027 028 /** 029 * Curried form of logical "inclusive or" (disjunction). 030 */ 031 public static final F<Boolean, F<Boolean, Boolean>> or = disjunctionSemigroup.sum(); 032 033 /** 034 * Curried form of logical "and" (conjunction). 035 */ 036 public static final F<Boolean, F<Boolean, Boolean>> and = conjunctionSemigroup.sum(); 037 038 039 /** 040 * Curried form of logical xor (nonequivalence). 041 */ 042 public static final F<Boolean, F<Boolean, Boolean>> xor = exclusiveDisjunctionSemiGroup.sum(); 043 044 /** 045 * Logical negation. 046 */ 047 public static final F<Boolean, Boolean> not = new F<Boolean, Boolean>() { 048 public Boolean f(final Boolean p) { 049 return !p; 050 } 051 }; 052 053 /** 054 * Curried form of logical "only if" (material implication). 055 */ 056 public static final F<Boolean, F<Boolean, Boolean>> implies = curry(new F2<Boolean, Boolean, Boolean>() { 057 public Boolean f(final Boolean p, final Boolean q) { 058 return !p || q; 059 } 060 }); 061 062 /** 063 * Curried form of logical "if" (reverse material implication). 064 */ 065 public static final F<Boolean, F<Boolean, Boolean>> if_ = flip(implies); 066 067 /** 068 * Curried form of logical "if and only if" (biconditional, equivalence). 069 */ 070 public static final F<Boolean, F<Boolean, Boolean>> iff = compose2(not, xor); 071 072 /** 073 * Curried form of logical "not implies" (nonimplication). 074 */ 075 public static final F<Boolean, F<Boolean, Boolean>> nimp = compose2(not, implies); 076 077 /** 078 * Curried form of logical "not if" (reverse nonimplication). 079 */ 080 public static final F<Boolean, F<Boolean, Boolean>> nif = compose2(not, if_); 081 082 /** 083 * Curried form of logical "not or". 084 */ 085 public static final F<Boolean, F<Boolean, Boolean>> nor = compose2(not, or); 086 087 /** 088 * Returns true if all the elements of the given list are true. 089 * 090 * @param l A list to check for all the elements being true. 091 * @return true if all the elements of the given list are true. False otherwise. 092 */ 093 public static boolean and(final List<Boolean> l) { 094 return Monoid.conjunctionMonoid.sumLeft(l); 095 } 096 097 /** 098 * Returns true if all the elements of the given stream are true. 099 * 100 * @param l A stream to check for all the elements being true. 101 * @return true if all the elements of the given stream are true. False otherwise. 102 */ 103 public static boolean and(final Stream<Boolean> l) { 104 return Monoid.conjunctionMonoid.sumLeft(l); 105 } 106 107 /** 108 * Returns true if any element of the given list is true. 109 * 110 * @param l A list to check for any element being true. 111 * @return true if any element of the given list is true. False otherwise. 112 */ 113 public static boolean or(final List<Boolean> l) { 114 return Monoid.disjunctionMonoid.sumLeft(l); 115 } 116 117 /** 118 * Returns true if any element of the given stream is true. 119 * 120 * @param l A stream to check for any element being true. 121 * @return true if any element of the given stream is true. False otherwise. 122 */ 123 public static boolean or(final Stream<Boolean> l) { 124 return Monoid.disjunctionMonoid.sumLeft(l); 125 } 126 127 /** 128 * Negates the given predicate. 129 * 130 * @param p A predicate to negate. 131 * @return The negation of the given predicate. 132 */ 133 public static <A> F<A, Boolean> not(final F<A, Boolean> p) { 134 return compose(not, p); 135 } 136 137 /** 138 * Curried form of conditional. If the first argument is true, returns the second argument, 139 * otherwise the third argument. 140 * 141 * @return A function that returns its second argument if the first argument is true, otherwise the third argument. 142 */ 143 public static <A> F<Boolean, F<A, F<A, A>>> cond() { 144 return curry(new F3<Boolean, A, A, A>() { 145 public A f(final Boolean p, final A a1, final A a2) { 146 return p ? a1 : a2; 147 } 148 }); 149 } 150 }