Mercurial > hg > Members > tatsuki > functionaljava-master > core
comparison src/main/java/fj/Monoid.java @ 0:fe80c1edf1be
add getLoop
author | tatsuki |
---|---|
date | Fri, 20 Mar 2015 21:04:03 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:fe80c1edf1be |
---|---|
1 package fj; | |
2 | |
3 import static fj.Function.curry; | |
4 import static fj.Function.compose; | |
5 import static fj.Function.flip; | |
6 import fj.data.Array; | |
7 import fj.data.List; | |
8 import fj.data.Natural; | |
9 import fj.data.Option; | |
10 import fj.data.Set; | |
11 import fj.data.Stream; | |
12 import static fj.data.Stream.iterableStream; | |
13 | |
14 import java.math.BigInteger; | |
15 import java.math.BigDecimal; | |
16 | |
17 /** | |
18 * A monoid abstraction to be defined across types of the given type argument. Implementations must | |
19 * follow the monoidal laws: | |
20 * <ul> | |
21 * <li><em>Left Identity</em>; forall x. sum(zero(), x) == x</li> | |
22 * <li><em>Right Identity</em>; forall x. sum(x, zero()) == x</li> | |
23 * <li><em>Associativity</em>; forall x. forall y. forall z. sum(sum(x, y), z) == sum(x, sum(y, z))</li> | |
24 * </ul> | |
25 * | |
26 * @version %build.number% | |
27 */ | |
28 public final class Monoid<A> { | |
29 private final F<A, F<A, A>> sum; | |
30 private final A zero; | |
31 | |
32 private Monoid(final F<A, F<A, A>> sum, final A zero) { | |
33 this.sum = sum; | |
34 this.zero = zero; | |
35 } | |
36 | |
37 /** | |
38 * Returns a semigroup projection of this monoid. | |
39 * | |
40 * @return A semigroup projection of this monoid. | |
41 */ | |
42 public Semigroup<A> semigroup() { | |
43 return Semigroup.semigroup(sum); | |
44 } | |
45 | |
46 /** | |
47 * Sums the two given arguments. | |
48 * | |
49 * @param a1 A value to sum with another. | |
50 * @param a2 A value to sum with another. | |
51 * @return The of the two given arguments. | |
52 */ | |
53 public A sum(final A a1, final A a2) { | |
54 return sum.f(a1).f(a2); | |
55 } | |
56 | |
57 /** | |
58 * Returns a function that sums the given value according to this monoid. | |
59 * | |
60 * @param a1 The value to sum. | |
61 * @return A function that sums the given value according to this monoid. | |
62 */ | |
63 public F<A, A> sum(final A a1) { | |
64 return sum.f(a1); | |
65 } | |
66 | |
67 /** | |
68 * Returns a function that sums according to this monoid. | |
69 * | |
70 * @return A function that sums according to this monoid. | |
71 */ | |
72 public F<A, F<A, A>> sum() { | |
73 return sum; | |
74 } | |
75 | |
76 /** | |
77 * The zero value for this monoid. | |
78 * | |
79 * @return The zero value for this monoid. | |
80 */ | |
81 public A zero() { | |
82 return zero; | |
83 } | |
84 | |
85 /** | |
86 * Sums the given values with right-fold. | |
87 * | |
88 * @param as The values to sum. | |
89 * @return The sum of the given values. | |
90 */ | |
91 public A sumRight(final List<A> as) { | |
92 return as.foldRight(sum, zero); | |
93 } | |
94 | |
95 /** | |
96 * Sums the given values with right-fold. | |
97 * | |
98 * @param as The values to sum. | |
99 * @return The sum of the given values. | |
100 */ | |
101 public A sumRight(final Stream<A> as) { | |
102 return as.foldRight(new F2<A, P1<A>, A>() { | |
103 public A f(final A a, final P1<A> ap1) { | |
104 return sum(a, ap1._1()); | |
105 } | |
106 }, zero); | |
107 } | |
108 | |
109 /** | |
110 * Sums the given values with left-fold. | |
111 * | |
112 * @param as The values to sum. | |
113 * @return The sum of the given values. | |
114 */ | |
115 public A sumLeft(final List<A> as) { | |
116 return as.foldLeft(sum, zero); | |
117 } | |
118 | |
119 /** | |
120 * Sums the given values with left-fold. | |
121 * | |
122 * @param as The values to sum. | |
123 * @return The sum of the given values. | |
124 */ | |
125 public A sumLeft(final Stream<A> as) { | |
126 return as.foldLeft(sum, zero); | |
127 } | |
128 | |
129 /** | |
130 * Returns a function that sums the given values with left-fold. | |
131 * | |
132 * @return a function that sums the given values with left-fold. | |
133 */ | |
134 public F<List<A>, A> sumLeft() { | |
135 return new F<List<A>, A>() { | |
136 public A f(final List<A> as) { | |
137 return sumLeft(as); | |
138 } | |
139 }; | |
140 } | |
141 | |
142 /** | |
143 * Returns a function that sums the given values with right-fold. | |
144 * | |
145 * @return a function that sums the given values with right-fold. | |
146 */ | |
147 public F<List<A>, A> sumRight() { | |
148 return new F<List<A>, A>() { | |
149 public A f(final List<A> as) { | |
150 return sumRight(as); | |
151 } | |
152 }; | |
153 } | |
154 | |
155 /** | |
156 * Returns a function that sums the given values with left-fold. | |
157 * | |
158 * @return a function that sums the given values with left-fold. | |
159 */ | |
160 public F<Stream<A>, A> sumLeftS() { | |
161 return new F<Stream<A>, A>() { | |
162 public A f(final Stream<A> as) { | |
163 return sumLeft(as); | |
164 } | |
165 }; | |
166 } | |
167 | |
168 /** | |
169 * Intersperses the given value between each two elements of the iterable, and sums the result. | |
170 * | |
171 * @param as An iterable of values to sum. | |
172 * @param a The value to intersperse between values of the given iterable. | |
173 * @return The sum of the given values and the interspersed value. | |
174 */ | |
175 public A join(final Iterable<A> as, final A a) { | |
176 final Stream<A> s = iterableStream(as); | |
177 return s.isEmpty() ? | |
178 zero : | |
179 s.foldLeft1(compose(sum, flip(sum).f(a))); | |
180 } | |
181 | |
182 /** | |
183 * Constructs a monoid from the given sum function and zero value, which must follow the monoidal | |
184 * laws. | |
185 * | |
186 * @param sum The sum function for the monoid. | |
187 * @param zero The zero for the monoid. | |
188 * @return A monoid instance that uses the given sun function and zero value. | |
189 */ | |
190 public static <A> Monoid<A> monoid(final F<A, F<A, A>> sum, final A zero) { | |
191 return new Monoid<A>(sum, zero); | |
192 } | |
193 | |
194 /** | |
195 * Constructs a monoid from the given sum function and zero value, which must follow the monoidal | |
196 * laws. | |
197 * | |
198 * @param sum The sum function for the monoid. | |
199 * @param zero The zero for the monoid. | |
200 * @return A monoid instance that uses the given sun function and zero value. | |
201 */ | |
202 public static <A> Monoid<A> monoid(final F2<A, A, A> sum, final A zero) { | |
203 return new Monoid<A>(curry(sum), zero); | |
204 } | |
205 | |
206 /** | |
207 * Constructs a monoid from the given semigroup and zero value, which must follow the monoidal laws. | |
208 * | |
209 * @param s The semigroup for the monoid. | |
210 * @param zero The zero for the monoid. | |
211 * @return A monoid instance that uses the given sun function and zero value. | |
212 */ | |
213 public static <A> Monoid<A> monoid(final Semigroup<A> s, final A zero) { | |
214 return new Monoid<A>(s.sum(), zero); | |
215 } | |
216 | |
217 /** | |
218 * A monoid that adds integers. | |
219 */ | |
220 public static final Monoid<Integer> intAdditionMonoid = monoid(Semigroup.intAdditionSemigroup, 0); | |
221 | |
222 /** | |
223 * A monoid that multiplies integers. | |
224 */ | |
225 public static final Monoid<Integer> intMultiplicationMonoid = monoid(Semigroup.intMultiplicationSemigroup, 1); | |
226 | |
227 /** | |
228 * A monoid that adds doubles. | |
229 */ | |
230 public static final Monoid<Double> doubleAdditionMonoid = monoid(Semigroup.doubleAdditionSemigroup, 0.0); | |
231 | |
232 /** | |
233 * A monoid that multiplies doubles. | |
234 */ | |
235 public static final Monoid<Double> doubleMultiplicationMonoid = monoid(Semigroup.doubleMultiplicationSemigroup, 1.0); | |
236 | |
237 /** | |
238 * A monoid that adds big integers. | |
239 */ | |
240 public static final Monoid<BigInteger> bigintAdditionMonoid = monoid(Semigroup.bigintAdditionSemigroup, BigInteger.ZERO); | |
241 | |
242 /** | |
243 * A monoid that multiplies big integers. | |
244 */ | |
245 public static final Monoid<BigInteger> bigintMultiplicationMonoid = | |
246 monoid(Semigroup.bigintMultiplicationSemigroup, BigInteger.ONE); | |
247 | |
248 /** | |
249 * A monoid that adds big decimals. | |
250 */ | |
251 public static final Monoid<BigDecimal> bigdecimalAdditionMonoid = | |
252 monoid(Semigroup.bigdecimalAdditionSemigroup, BigDecimal.ZERO); | |
253 | |
254 /** | |
255 * A monoid that multiplies big decimals. | |
256 */ | |
257 public static final Monoid<BigDecimal> bigdecimalMultiplicationMonoid = | |
258 monoid(Semigroup.bigdecimalMultiplicationSemigroup, BigDecimal.ONE); | |
259 | |
260 /** | |
261 * A monoid that adds natural numbers. | |
262 */ | |
263 public static final Monoid<Natural> naturalAdditionMonoid = | |
264 monoid(Semigroup.naturalAdditionSemigroup, Natural.ZERO); | |
265 | |
266 /** | |
267 * A monoid that multiplies natural numbers. | |
268 */ | |
269 public static final Monoid<Natural> naturalMultiplicationMonoid = | |
270 monoid(Semigroup.naturalMultiplicationSemigroup, Natural.ONE); | |
271 | |
272 /** | |
273 * A monoid that adds longs. | |
274 */ | |
275 public static final Monoid<Long> longAdditionMonoid = monoid(Semigroup.longAdditionSemigroup, 0L); | |
276 | |
277 /** | |
278 * A monoid that multiplies longs. | |
279 */ | |
280 public static final Monoid<Long> longMultiplicationMonoid = monoid(Semigroup.longMultiplicationSemigroup, 1L); | |
281 | |
282 /** | |
283 * A monoid that ORs booleans. | |
284 */ | |
285 public static final Monoid<Boolean> disjunctionMonoid = monoid(Semigroup.disjunctionSemigroup, false); | |
286 | |
287 /** | |
288 * A monoid that XORs booleans. | |
289 */ | |
290 public static final Monoid<Boolean> exclusiveDisjunctionMonoid = monoid(Semigroup.exclusiveDisjunctionSemiGroup, false); | |
291 | |
292 /** | |
293 * A monoid that ANDs booleans. | |
294 */ | |
295 public static final Monoid<Boolean> conjunctionMonoid = monoid(Semigroup.conjunctionSemigroup, true); | |
296 | |
297 /** | |
298 * A monoid that appends strings. | |
299 */ | |
300 public static final Monoid<String> stringMonoid = monoid(Semigroup.stringSemigroup, ""); | |
301 | |
302 /** | |
303 * A monoid that appends string buffers. | |
304 */ | |
305 public static final Monoid<StringBuffer> stringBufferMonoid = monoid(Semigroup.stringBufferSemigroup, new StringBuffer()); | |
306 | |
307 /** | |
308 * A monoid that appends string builders. | |
309 */ | |
310 public static final Monoid<StringBuilder> stringBuilderMonoid = monoid(Semigroup.stringBuilderSemigroup, new StringBuilder()); | |
311 | |
312 /** | |
313 * A monoid for functions. | |
314 * | |
315 * @param mb The monoid for the function codomain. | |
316 * @return A monoid for functions. | |
317 */ | |
318 public static <A, B> Monoid<F<A, B>> functionMonoid(final Monoid<B> mb) { | |
319 return monoid(Semigroup.<A, B>functionSemigroup(mb.semigroup()), Function.<A, B>constant(mb.zero)); | |
320 } | |
321 | |
322 /** | |
323 * A monoid for lists. | |
324 * | |
325 * @return A monoid for lists. | |
326 */ | |
327 public static <A> Monoid<List<A>> listMonoid() { | |
328 return monoid(Semigroup.<A>listSemigroup(), List.<A>nil()); | |
329 } | |
330 | |
331 /** | |
332 * A monoid for options. | |
333 * | |
334 * @return A monoid for options. | |
335 */ | |
336 public static <A> Monoid<Option<A>> optionMonoid() { | |
337 return monoid(Semigroup.<A>optionSemigroup(), Option.<A>none()); | |
338 } | |
339 | |
340 /** | |
341 * A monoid for options that take the first available value. | |
342 * | |
343 * @return A monoid for options that take the first available value. | |
344 */ | |
345 public static <A> Monoid<Option<A>> firstOptionMonoid() { | |
346 return monoid(Semigroup.<A>firstOptionSemigroup(), Option.<A>none()); | |
347 } | |
348 | |
349 /** | |
350 * A monoid for options that take the last available value. | |
351 * | |
352 * @return A monoid for options that take the last available value. | |
353 */ | |
354 public static <A> Monoid<Option<A>> lastOptionMonoid() { | |
355 return monoid(Semigroup.<A>lastOptionSemigroup(), Option.<A>none()); | |
356 } | |
357 | |
358 /** | |
359 * A monoid for streams. | |
360 * | |
361 * @return A monoid for streams. | |
362 */ | |
363 public static <A> Monoid<Stream<A>> streamMonoid() { | |
364 return monoid(Semigroup.<A>streamSemigroup(), Stream.<A>nil()); | |
365 } | |
366 | |
367 /** | |
368 * A monoid for arrays. | |
369 * | |
370 * @return A monoid for arrays. | |
371 */ | |
372 @SuppressWarnings({"unchecked"}) | |
373 public static <A> Monoid<Array<A>> arrayMonoid() { | |
374 return monoid(Semigroup.<A>arraySemigroup(), Array.<A>empty()); | |
375 } | |
376 | |
377 /** | |
378 * A monoid for sets. | |
379 * | |
380 * @param o An order for set elements. | |
381 * @return A monoid for sets whose elements have the given order. | |
382 */ | |
383 public static <A> Monoid<Set<A>> setMonoid(final Ord<A> o) { | |
384 return monoid(Semigroup.<A>setSemigroup(), Set.empty(o)); | |
385 } | |
386 | |
387 } |