001 package fj; 002 003 import static fj.FW.$; 004 005 /** 006 * A product-4. 007 * 008 * @version %build.number%<br> 009 * <ul> 010 * <li>$LastChangedRevision: 270 $</li> 011 * <li>$LastChangedDate: 2009-07-28 14:06:27 +1000 (Tue, 28 Jul 2009) $</li> 012 * </ul> 013 */ 014 public abstract class P4<A, B, C, D> { 015 /** 016 * Access the first element of the product. 017 * 018 * @return The first element of the product. 019 */ 020 public abstract A _1(); 021 022 /** 023 * Access the second element of the product. 024 * 025 * @return The second element of the product. 026 */ 027 public abstract B _2(); 028 029 /** 030 * Access the third element of the product. 031 * 032 * @return The third element of the product. 033 */ 034 public abstract C _3(); 035 036 /** 037 * Access the fourth element of the product. 038 * 039 * @return The fourth element of the product. 040 */ 041 public abstract D _4(); 042 043 /** 044 * Map the first element of the product. 045 * 046 * @param f The function to map with. 047 * @return A product with the given function applied. 048 */ 049 public <X> P4<X, B, C, D> map1(final F<A, X> f) { 050 return new P4<X, B, C, D>() { 051 public X _1() { 052 return f.f(P4.this._1()); 053 } 054 055 public B _2() { 056 return P4.this._2(); 057 } 058 059 public C _3() { 060 return P4.this._3(); 061 } 062 063 public D _4() { 064 return P4.this._4(); 065 } 066 }; 067 } 068 069 /** 070 * Map the second element of the product. 071 * 072 * @param f The function to map with. 073 * @return A product with the given function applied. 074 */ 075 public <X> P4<A, X, C, D> map2(final F<B, X> f) { 076 return new P4<A, X, C, D>() { 077 public A _1() { 078 return P4.this._1(); 079 } 080 081 public X _2() { 082 return f.f(P4.this._2()); 083 } 084 085 public C _3() { 086 return P4.this._3(); 087 } 088 089 public D _4() { 090 return P4.this._4(); 091 } 092 }; 093 } 094 095 /** 096 * Map the third element of the product. 097 * 098 * @param f The function to map with. 099 * @return A product with the given function applied. 100 */ 101 public <X> P4<A, B, X, D> map3(final F<C, X> f) { 102 return new P4<A, B, X, D>() { 103 public A _1() { 104 return P4.this._1(); 105 } 106 107 public B _2() { 108 return P4.this._2(); 109 } 110 111 public X _3() { 112 return f.f(P4.this._3()); 113 } 114 115 public D _4() { 116 return P4.this._4(); 117 } 118 }; 119 } 120 121 /** 122 * Map the fourth element of the product. 123 * 124 * @param f The function to map with. 125 * @return A product with the given function applied. 126 */ 127 public <X> P4<A, B, C, X> map4(final F<D, X> f) { 128 return new P4<A, B, C, X>() { 129 public A _1() { 130 return P4.this._1(); 131 } 132 133 public B _2() { 134 return P4.this._2(); 135 } 136 137 public C _3() { 138 return P4.this._3(); 139 } 140 141 public X _4() { 142 return f.f(P4.this._4()); 143 } 144 }; 145 } 146 147 /** 148 * Returns the 1-product projection over the first element. 149 * 150 * @return the 1-product projection over the first element. 151 */ 152 public P1<A> _1_() { 153 return $(P4.<A, B, C, D>__1()).lazy().f(this); 154 } 155 156 /** 157 * Returns the 1-product projection over the second element. 158 * 159 * @return the 1-product projection over the second element. 160 */ 161 public P1<B> _2_() { 162 return $(P4.<A, B, C, D>__2()).lazy().f(this); 163 } 164 165 /** 166 * Returns the 1-product projection over the third element. 167 * 168 * @return the 1-product projection over the third element. 169 */ 170 public P1<C> _3_() { 171 return $(P4.<A, B, C, D>__3()).lazy().f(this); 172 } 173 174 /** 175 * Returns the 1-product projection over the fourth element. 176 * 177 * @return the 1-product projection over the fourth element. 178 */ 179 public P1<D> _4_() { 180 return $(P4.<A, B, C, D>__4()).lazy().f(this); 181 } 182 183 /** 184 * Provides a memoising P4 that remembers its values. 185 * 186 * @return A P4 that calls this P4 once for any given element and remembers the value for subsequent calls. 187 */ 188 public P4<A, B, C, D> memo() { 189 return new P4<A, B, C, D>() { 190 private final P1<A> a = _1_().memo(); 191 private final P1<B> b = _2_().memo(); 192 private final P1<C> c = _3_().memo(); 193 private final P1<D> d = _4_().memo(); 194 195 public A _1() { 196 return a._1(); 197 } 198 199 public B _2() { 200 return b._1(); 201 } 202 203 public C _3() { 204 return c._1(); 205 } 206 207 public D _4() { 208 return d._1(); 209 } 210 }; 211 } 212 213 214 /** 215 * Returns a function that returns the first element of a product. 216 * 217 * @return A function that returns the first element of a product. 218 */ 219 public static <A, B, C, D> F<P4<A, B, C, D>, A> __1() { 220 return new F<P4<A, B, C, D>, A>() { 221 public A f(final P4<A, B, C, D> p) { 222 return p._1(); 223 } 224 }; 225 } 226 227 /** 228 * Returns a function that returns the second element of a product. 229 * 230 * @return A function that returns the second element of a product. 231 */ 232 public static <A, B, C, D> F<P4<A, B, C, D>, B> __2() { 233 return new F<P4<A, B, C, D>, B>() { 234 public B f(final P4<A, B, C, D> p) { 235 return p._2(); 236 } 237 }; 238 } 239 240 /** 241 * Returns a function that returns the third element of a product. 242 * 243 * @return A function that returns the third element of a product. 244 */ 245 public static <A, B, C, D> F<P4<A, B, C, D>, C> __3() { 246 return new F<P4<A, B, C, D>, C>() { 247 public C f(final P4<A, B, C, D> p) { 248 return p._3(); 249 } 250 }; 251 } 252 253 /** 254 * Returns a function that returns the fourth element of a product. 255 * 256 * @return A function that returns the fourth element of a product. 257 */ 258 public static <A, B, C, D> F<P4<A, B, C, D>, D> __4() { 259 return new F<P4<A, B, C, D>, D>() { 260 public D f(final P4<A, B, C, D> p) { 261 return p._4(); 262 } 263 }; 264 } 265 }