File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1717import static fj .data .List .nil ;
1818import static fj .data .Natural .natural ;
1919import static fj .data .Option .none ;
20+ import static fj .data .Option .some ;
2021import static fj .data .Stream .iterableStream ;
2122
2223import java .math .BigInteger ;
@@ -867,6 +868,36 @@ public List<A> sum(F0<Stream<List<A>>> as) {
867868 });
868869 }
869870
871+ /**
872+ * Lift a {@code Semigroup<A>} for A to a {@code Monoid<Option<A>>}, using Option.none() as zero.
873+ *
874+ * @return A monoid for option.
875+ */
876+ public static <A > Monoid <Option <A >> optionMonoid (Semigroup <A > aSemigroup ) {
877+ return monoidDef (new Monoid .Definition <Option <A >>() {
878+ @ Override
879+ public Option <A > empty () {
880+ return none ();
881+ }
882+
883+ @ Override
884+ public Option <A > append (Option <A > a1 , Option <A > a2 ) {
885+ return a1 .liftM2 (a2 , aSemigroup ::sum ).orElse (a1 ).orElse (a2 );
886+ }
887+
888+ @ Override
889+ public Option <A > multiply (int n , Option <A > oa ) {
890+ return n > 0 ? oa .map (a -> aSemigroup .multiply1p (n - 1 , a )) : none ();
891+ }
892+
893+ @ Override
894+ public Option <A > sum (F0 <Stream <Option <A >>> oas ) {
895+ Stream <A > as = oas .f ().bind (Option ::toStream );
896+ return as .uncons (none (), h -> tail -> some (aSemigroup .sumStream (h , tail ::_1 )));
897+ }
898+ });
899+ }
900+
870901 /**
871902 * A monoid for options.
872903 * @deprecated since 4.7. Use {@link #firstOptionMonoid()}.
Original file line number Diff line number Diff line change @@ -172,29 +172,7 @@ public Semigroup<A> dual() {
172172 * Lifts the semigroup to obtain a trivial monoid.
173173 */
174174 public Monoid <Option <A >> lift () {
175- Definition <A > def = this .def ;
176- return monoidDef (new Monoid .Definition <Option <A >>() {
177- @ Override
178- public Option <A > empty () {
179- return none ();
180- }
181-
182- @ Override
183- public Option <A > append (Option <A > a1 , Option <A > a2 ) {
184- return a1 .liftM2 (a1 , def ::append ).orElse (a1 ).orElse (a2 );
185- }
186-
187- @ Override
188- public Option <A > multiply (int n , Option <A > oa ) {
189- return n > 0 ? oa .map (a -> def .multiply1p (n - 1 , a )) : none ();
190- }
191-
192- @ Override
193- public Option <A > sum (F0 <Stream <Option <A >>> oas ) {
194- Stream <A > as = oas .f ().bind (Option ::toStream );
195- return as .uncons (none (), h -> tail -> some (def .sum (h , tail ::_1 )));
196- }
197- });
175+ return Monoid .optionMonoid (this );
198176 }
199177
200178 /**
Original file line number Diff line number Diff line change 1+ package fj ;
2+
3+ import fj .data .Option ;
4+ import fj .data .Stream ;
5+ import org .junit .Test ;
6+
7+ import static fj .data .Option .some ;
8+ import static org .hamcrest .core .Is .is ;
9+ import static org .junit .Assert .assertThat ;
10+
11+ public class MonoidTest {
12+
13+ @ Test
14+ public void lifted_sum_of_two_numbers () {
15+ Monoid <Option <Integer >> optionMonoid = Semigroup .intAdditionSemigroup .lift ();
16+ assertThat (optionMonoid .sum (some (3 ), some (5 )), is (some (8 )));
17+ assertThat (optionMonoid .sumLeft (Stream .arrayStream (some (3 ), some (5 ))), is (some (8 )));
18+ }
19+ }
You can’t perform that action at this time.
0 commit comments