001 package fj; 002 003 import static fj.FW.$; 004 005 /** 006 * A product-3. 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 P3<A, B, C> { 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 * Map the first element of the product. 038 * 039 * @param f The function to map with. 040 * @return A product with the given function applied. 041 */ 042 public <X> P3<X, B, C> map1(final F<A, X> f) { 043 return new P3<X, B, C>() { 044 public X _1() { 045 return f.f(P3.this._1()); 046 } 047 048 public B _2() { 049 return P3.this._2(); 050 } 051 052 public C _3() { 053 return P3.this._3(); 054 } 055 }; 056 } 057 058 /** 059 * Map the second element of the product. 060 * 061 * @param f The function to map with. 062 * @return A product with the given function applied. 063 */ 064 public <X> P3<A, X, C> map2(final F<B, X> f) { 065 return new P3<A, X, C>() { 066 public A _1() { 067 return P3.this._1(); 068 } 069 070 public X _2() { 071 return f.f(P3.this._2()); 072 } 073 074 public C _3() { 075 return P3.this._3(); 076 } 077 }; 078 } 079 080 /** 081 * Map the third element of the product. 082 * 083 * @param f The function to map with. 084 * @return A product with the given function applied. 085 */ 086 public <X> P3<A, B, X> map3(final F<C, X> f) { 087 return new P3<A, B, X>() { 088 public A _1() { 089 return P3.this._1(); 090 } 091 092 public B _2() { 093 return P3.this._2(); 094 } 095 096 public X _3() { 097 return f.f(P3.this._3()); 098 } 099 }; 100 } 101 102 /** 103 * Returns the 1-product projection over the first element. 104 * 105 * @return the 1-product projection over the first element. 106 */ 107 public P1<A> _1_() { 108 return $(P3.<A, B, C>__1()).lazy().f(this); 109 } 110 111 /** 112 * Returns the 1-product projection over the second element. 113 * 114 * @return the 1-product projection over the second element. 115 */ 116 public P1<B> _2_() { 117 return $(P3.<A, B, C>__2()).lazy().f(this); 118 } 119 120 /** 121 * Returns the 1-product projection over the third element. 122 * 123 * @return the 1-product projection over the third element. 124 */ 125 public P1<C> _3_() { 126 return $(P3.<A, B, C>__3()).lazy().f(this); 127 } 128 129 /** 130 * Provides a memoising P3 that remembers its values. 131 * 132 * @return A P3 that calls this P3 once for any given element and remembers the value for subsequent calls. 133 */ 134 public P3<A, B, C> memo() { 135 return new P3<A, B, C>() { 136 private final P1<A> a = _1_().memo(); 137 private final P1<B> b = _2_().memo(); 138 private final P1<C> c = _3_().memo(); 139 140 public A _1() { 141 return a._1(); 142 } 143 144 public B _2() { 145 return b._1(); 146 } 147 148 public C _3() { 149 return c._1(); 150 } 151 }; 152 } 153 154 /** 155 * Returns a function that returns the first element of a product. 156 * 157 * @return A function that returns the first element of a product. 158 */ 159 public static <A, B, C> F<P3<A, B, C>, A> __1() { 160 return new F<P3<A, B, C>, A>() { 161 public A f(final P3<A, B, C> p) { 162 return p._1(); 163 } 164 }; 165 } 166 167 /** 168 * Returns a function that returns the second element of a product. 169 * 170 * @return A function that returns the second element of a product. 171 */ 172 public static <A, B, C> F<P3<A, B, C>, B> __2() { 173 return new F<P3<A, B, C>, B>() { 174 public B f(final P3<A, B, C> p) { 175 return p._2(); 176 } 177 }; 178 } 179 180 /** 181 * Returns a function that returns the third element of a product. 182 * 183 * @return A function that returns the third element of a product. 184 */ 185 public static <A, B, C> F<P3<A, B, C>, C> __3() { 186 return new F<P3<A, B, C>, C>() { 187 public C f(final P3<A, B, C> p) { 188 return p._3(); 189 } 190 }; 191 } 192 }