Skip to content

Commit 4ac6ee3

Browse files
committed
Replacing Optional with Maybe across the board
1 parent a593cf3 commit 4ac6ee3

63 files changed

Lines changed: 772 additions & 573 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
88
- `CoProductN#embed` no longer eagerly invokes functions
99

1010
### Added
11+
- `Monad` arrives. The following `Applicative`s are now also `Monad`:
12+
- `Lens`
13+
- `Const`
14+
- `Tuple*`
15+
- `Choice*`
16+
- `Identity`
17+
- `Either`
18+
- `Fn*`
19+
- `LambdaIterable`
20+
- `Maybe`
21+
- `SingletonHList`
1122
- `Force`, for forcing iteration of an `Iterable` to perform any side-effects
1223
- `Snoc`, for lazily appending an element to the end of an `Iterable`
1324
- `Coalesce`, for folding an `Iterable<Either<L, R>>` into an `Either<Iterable<L>, Iterable<R>>`
@@ -26,9 +37,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
2637
- `Traversables` and all methods therein, in favor of either `LambdaIterable` or `Maybe`
2738
- `TraversableOptional` in favor of `Maybe`
2839
- `TraversableIterable` in favor of `LambdaIterable`
40+
- `Sequence` overloads supporting `Optional` in favor of converting `Optional` to `Maybe` and then sequencing
41+
- `Either#toOptional` and `Either#fromOptional` in favor of its `Maybe` counterparts
2942

3043
### Changed
44+
- ***Breaking Change***: `java.util.Optional` replaced with `Maybe` across the board
3145
- `Profunctor#diMap/L/R` parameters allow variance
46+
- `Either#toOptional` no longer allows `null` values in the right side, and is now in sync with CoProduct#projectB
47+
- `Unfoldr` allows variance on input
3248

3349
## [1.6.3] - 2017-09-27
3450
### Fixed

src/main/java/com/jnape/palatable/lambda/adt/Either.java

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,21 @@ public <R2, App extends Applicative> Applicative<Either<L, R2>, App> traverse(
249249
* right value.
250250
*
251251
* @return an Optional around the right value, or empty if left
252+
* @deprecated in favor of {@link Either#toMaybe()}
252253
*/
254+
@Deprecated
253255
public Optional<R> toOptional() {
254-
return match(__ -> Optional.empty(), Optional::ofNullable);
256+
return toMaybe().toOptional();
257+
}
258+
259+
/**
260+
* In the left case, returns a {@link Maybe#nothing()}; otherwise, returns {@link Maybe#maybe} around the right
261+
* value.
262+
*
263+
* @return Maybe the right value
264+
*/
265+
public Maybe<R> toMaybe() {
266+
return projectB();
255267
}
256268

257269
/**
@@ -263,9 +275,25 @@ public Optional<R> toOptional() {
263275
* @param <L> the left parameter type
264276
* @param <R> the right parameter type
265277
* @return a right value of the contained optional value, or a left value of leftFn's result
278+
* @deprecated in favor of converting {@link Optional} to {@link Maybe}, then using {@link Either#fromMaybe}
266279
*/
280+
@Deprecated
267281
public static <L, R> Either<L, R> fromOptional(Optional<R> optional, Supplier<L> leftFn) {
268-
return optional.<Either<L, R>>map(Either::right)
282+
return fromMaybe(Maybe.fromOptional(optional), leftFn);
283+
}
284+
285+
/**
286+
* Convert a {@link Maybe}&lt;R&gt; into an <code>Either&lt;L, R&gt;</code>, supplying the left value from
287+
* <code>leftFn</code> in the case of {@link Maybe#nothing()}.
288+
*
289+
* @param maybe the maybe
290+
* @param leftFn the supplier to use for left values
291+
* @param <L> the left parameter type
292+
* @param <R> the right parameter type
293+
* @return a right value of the contained maybe value, or a left value of leftFn's result
294+
*/
295+
public static <L, R> Either<L, R> fromMaybe(Maybe<R> maybe, Supplier<L> leftFn) {
296+
return maybe.<Either<L, R>>fmap(Either::right)
269297
.orElseGet(() -> left(leftFn.get()));
270298
}
271299

src/main/java/com/jnape/palatable/lambda/adt/Maybe.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public final A orElse(A other) {
5454
* @return the value, if present
5555
* @throws E the throwable, if the value is absent
5656
*/
57-
public final <E extends Throwable> A orThrow(Supplier<E> throwableSupplier) throws E {
57+
public final <E extends Throwable> A orElseThrow(Supplier<E> throwableSupplier) throws E {
5858
return orElseGet((CheckedSupplier<E, A>) () -> {
5959
throw throwableSupplier.get();
6060
});
@@ -243,9 +243,7 @@ public int hashCode() {
243243

244244
@Override
245245
public String toString() {
246-
return "Just{" +
247-
"a=" + a +
248-
'}';
246+
return "Just " + a;
249247
}
250248
}
251249

@@ -276,7 +274,7 @@ public A orElseGet(Supplier<A> otherSupplier) {
276274

277275
@Override
278276
public String toString() {
279-
return "Nothing{}";
277+
return "Nothing";
280278
}
281279
}
282280
}

src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct2.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package com.jnape.palatable.lambda.adt.coproduct;
22

33
import com.jnape.palatable.lambda.adt.Either;
4+
import com.jnape.palatable.lambda.adt.Maybe;
45
import com.jnape.palatable.lambda.adt.choice.Choice2;
56
import com.jnape.palatable.lambda.adt.hlist.Tuple2;
67
import com.jnape.palatable.lambda.functions.Fn1;
78

8-
import java.util.Optional;
99
import java.util.function.Function;
1010

11+
import static com.jnape.palatable.lambda.adt.Maybe.just;
12+
import static com.jnape.palatable.lambda.adt.Maybe.nothing;
1113
import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
1214
import static com.jnape.palatable.lambda.functions.Fn1.fn1;
1315
import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
@@ -74,17 +76,17 @@ public <R> R match(Function<? super A, ? extends R> aFn, Function<? super B, ? e
7476
*
7577
* @return a tuple of the coproduct projection
7678
*/
77-
default Tuple2<Optional<A>, Optional<B>> project() {
78-
return match(a -> tuple(Optional.of(a), Optional.empty()),
79-
b -> tuple(Optional.empty(), Optional.of(b)));
79+
default Tuple2<Maybe<A>, Maybe<B>> project() {
80+
return match(a -> tuple(just(a), nothing()),
81+
b -> tuple(nothing(), just(b)));
8082
}
8183

8284
/**
8385
* Convenience method for projecting this coproduct onto a tuple and then extracting the first slot value.
8486
*
8587
* @return an optional value representing the projection of the "a" type index
8688
*/
87-
default Optional<A> projectA() {
89+
default Maybe<A> projectA() {
8890
return project()._1();
8991
}
9092

@@ -93,7 +95,7 @@ default Optional<A> projectA() {
9395
*
9496
* @return an optional value representing the projection of the "b" type index
9597
*/
96-
default Optional<B> projectB() {
98+
default Maybe<B> projectB() {
9799
return project()._2();
98100
}
99101

src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct3.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package com.jnape.palatable.lambda.adt.coproduct;
22

3+
import com.jnape.palatable.lambda.adt.Maybe;
34
import com.jnape.palatable.lambda.adt.hlist.Tuple3;
45
import com.jnape.palatable.lambda.functions.Fn1;
56

6-
import java.util.Optional;
77
import java.util.function.Function;
88

9+
import static com.jnape.palatable.lambda.adt.Maybe.just;
10+
import static com.jnape.palatable.lambda.adt.Maybe.nothing;
911
import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
1012
import static com.jnape.palatable.lambda.functions.Fn1.fn1;
1113
import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
@@ -85,18 +87,18 @@ public <R> R match(Function<? super A, ? extends R> aFn, Function<? super B, ? e
8587
* @return a tuple of the coproduct projection
8688
* @see CoProduct2#project()
8789
*/
88-
default Tuple3<Optional<A>, Optional<B>, Optional<C>> project() {
89-
return match(a -> tuple(Optional.of(a), Optional.empty(), Optional.empty()),
90-
b -> tuple(Optional.empty(), Optional.of(b), Optional.empty()),
91-
c -> tuple(Optional.empty(), Optional.empty(), Optional.of(c)));
90+
default Tuple3<Maybe<A>, Maybe<B>, Maybe<C>> project() {
91+
return match(a -> tuple(just(a), nothing(), nothing()),
92+
b -> tuple(nothing(), just(b), nothing()),
93+
c -> tuple(nothing(), nothing(), just(c)));
9294
}
9395

9496
/**
9597
* Convenience method for projecting this coproduct onto a tuple and then extracting the first slot value.
9698
*
9799
* @return an optional value representing the projection of the "a" type index
98100
*/
99-
default Optional<A> projectA() {
101+
default Maybe<A> projectA() {
100102
return project()._1();
101103
}
102104

@@ -105,7 +107,7 @@ default Optional<A> projectA() {
105107
*
106108
* @return an optional value representing the projection of the "b" type index
107109
*/
108-
default Optional<B> projectB() {
110+
default Maybe<B> projectB() {
109111
return project()._2();
110112
}
111113

@@ -114,7 +116,7 @@ default Optional<B> projectB() {
114116
*
115117
* @return an optional value representing the projection of the "c" type index
116118
*/
117-
default Optional<C> projectC() {
119+
default Maybe<C> projectC() {
118120
return project()._3();
119121
}
120122

src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct4.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package com.jnape.palatable.lambda.adt.coproduct;
22

3+
import com.jnape.palatable.lambda.adt.Maybe;
34
import com.jnape.palatable.lambda.adt.hlist.Tuple4;
45
import com.jnape.palatable.lambda.functions.Fn1;
56

6-
import java.util.Optional;
77
import java.util.function.Function;
88

9+
import static com.jnape.palatable.lambda.adt.Maybe.just;
10+
import static com.jnape.palatable.lambda.adt.Maybe.nothing;
911
import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
1012
import static com.jnape.palatable.lambda.functions.Fn1.fn1;
1113
import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
@@ -93,19 +95,19 @@ public <R> R match(Function<? super A, ? extends R> aFn, Function<? super B, ? e
9395
* @return a tuple of the coproduct projection
9496
* @see CoProduct2#project()
9597
*/
96-
default Tuple4<Optional<A>, Optional<B>, Optional<C>, Optional<D>> project() {
97-
return match(a -> tuple(Optional.of(a), Optional.empty(), Optional.empty(), Optional.empty()),
98-
b -> tuple(Optional.empty(), Optional.of(b), Optional.empty(), Optional.empty()),
99-
c -> tuple(Optional.empty(), Optional.empty(), Optional.of(c), Optional.empty()),
100-
d -> tuple(Optional.empty(), Optional.empty(), Optional.empty(), Optional.of(d)));
98+
default Tuple4<Maybe<A>, Maybe<B>, Maybe<C>, Maybe<D>> project() {
99+
return match(a -> tuple(just(a), nothing(), nothing(), nothing()),
100+
b -> tuple(nothing(), just(b), nothing(), nothing()),
101+
c -> tuple(nothing(), nothing(), just(c), nothing()),
102+
d -> tuple(nothing(), nothing(), nothing(), just(d)));
101103
}
102104

103105
/**
104106
* Convenience method for projecting this coproduct onto a tuple and then extracting the first slot value.
105107
*
106108
* @return an optional value representing the projection of the "a" type index
107109
*/
108-
default Optional<A> projectA() {
110+
default Maybe<A> projectA() {
109111
return project()._1();
110112
}
111113

@@ -114,7 +116,7 @@ default Optional<A> projectA() {
114116
*
115117
* @return an optional value representing the projection of the "b" type index
116118
*/
117-
default Optional<B> projectB() {
119+
default Maybe<B> projectB() {
118120
return project()._2();
119121
}
120122

@@ -123,7 +125,7 @@ default Optional<B> projectB() {
123125
*
124126
* @return an optional value representing the projection of the "c" type index
125127
*/
126-
default Optional<C> projectC() {
128+
default Maybe<C> projectC() {
127129
return project()._3();
128130
}
129131

@@ -132,7 +134,7 @@ default Optional<C> projectC() {
132134
*
133135
* @return an optional value representing the projection of the "d" type index
134136
*/
135-
default Optional<D> projectD() {
137+
default Maybe<D> projectD() {
136138
return project()._4();
137139
}
138140

src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct5.java

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package com.jnape.palatable.lambda.adt.coproduct;
22

3+
import com.jnape.palatable.lambda.adt.Maybe;
34
import com.jnape.palatable.lambda.adt.hlist.Tuple5;
45
import com.jnape.palatable.lambda.functions.Fn1;
56

6-
import java.util.Optional;
77
import java.util.function.Function;
88

9+
import static com.jnape.palatable.lambda.adt.Maybe.just;
10+
import static com.jnape.palatable.lambda.adt.Maybe.nothing;
911
import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
1012
import static com.jnape.palatable.lambda.functions.Fn1.fn1;
1113
import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
@@ -84,20 +86,20 @@ public <R> R match(Function<? super A, ? extends R> aFn, Function<? super B, ? e
8486
* @return a tuple of the coproduct projection
8587
* @see CoProduct2#project()
8688
*/
87-
default Tuple5<Optional<A>, Optional<B>, Optional<C>, Optional<D>, Optional<E>> project() {
88-
return match(a -> tuple(Optional.of(a), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty()),
89-
b -> tuple(Optional.empty(), Optional.of(b), Optional.empty(), Optional.empty(), Optional.empty()),
90-
c -> tuple(Optional.empty(), Optional.empty(), Optional.of(c), Optional.empty(), Optional.empty()),
91-
d -> tuple(Optional.empty(), Optional.empty(), Optional.empty(), Optional.of(d), Optional.empty()),
92-
e -> tuple(Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.of(e)));
89+
default Tuple5<Maybe<A>, Maybe<B>, Maybe<C>, Maybe<D>, Maybe<E>> project() {
90+
return match(a -> tuple(just(a), nothing(), nothing(), nothing(), nothing()),
91+
b -> tuple(nothing(), just(b), nothing(), nothing(), nothing()),
92+
c -> tuple(nothing(), nothing(), just(c), nothing(), nothing()),
93+
d -> tuple(nothing(), nothing(), nothing(), just(d), nothing()),
94+
e -> tuple(nothing(), nothing(), nothing(), nothing(), just(e)));
9395
}
9496

9597
/**
9698
* Convenience method for projecting this coproduct onto a tuple and then extracting the first slot value.
9799
*
98100
* @return an optional value representing the projection of the "a" type index
99101
*/
100-
default Optional<A> projectA() {
102+
default Maybe<A> projectA() {
101103
return project()._1();
102104
}
103105

@@ -106,7 +108,7 @@ default Optional<A> projectA() {
106108
*
107109
* @return an optional value representing the projection of the "b" type index
108110
*/
109-
default Optional<B> projectB() {
111+
default Maybe<B> projectB() {
110112
return project()._2();
111113
}
112114

@@ -115,7 +117,7 @@ default Optional<B> projectB() {
115117
*
116118
* @return an optional value representing the projection of the "c" type index
117119
*/
118-
default Optional<C> projectC() {
120+
default Maybe<C> projectC() {
119121
return project()._3();
120122
}
121123

@@ -124,7 +126,7 @@ default Optional<C> projectC() {
124126
*
125127
* @return an optional value representing the projection of the "d" type index
126128
*/
127-
default Optional<D> projectD() {
129+
default Maybe<D> projectD() {
128130
return project()._4();
129131
}
130132

@@ -133,7 +135,7 @@ default Optional<D> projectD() {
133135
*
134136
* @return an optional value representing the projection of the "e" type index
135137
*/
136-
default Optional<E> projectE() {
138+
default Maybe<E> projectE() {
137139
return project()._5();
138140
}
139141

src/main/java/com/jnape/palatable/lambda/adt/hmap/HMap.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package com.jnape.palatable.lambda.adt.hmap;
22

3+
import com.jnape.palatable.lambda.adt.Maybe;
34
import com.jnape.palatable.lambda.adt.hlist.Tuple2;
45

56
import java.util.HashMap;
67
import java.util.Iterator;
78
import java.util.Map;
89
import java.util.NoSuchElementException;
910
import java.util.Objects;
10-
import java.util.Optional;
1111
import java.util.function.Consumer;
1212

1313
import static com.jnape.palatable.lambda.functions.builtin.fn2.Map.map;
@@ -36,11 +36,11 @@ private HMap(Map<TypeSafeKey, Object> table) {
3636
*
3737
* @param key the key
3838
* @param <T> the value type
39-
* @return the value at this key wrapped in an {@link Optional}, or {@link Optional#empty}.
39+
* @return Maybe the value at this key
4040
*/
4141
@SuppressWarnings("unchecked")
42-
public <T> Optional<T> get(TypeSafeKey<T> key) {
43-
return Optional.ofNullable((T) table.get(key));
42+
public <T> Maybe<T> get(TypeSafeKey<T> key) {
43+
return Maybe.maybe((T) table.get(key));
4444
}
4545

4646
/**

0 commit comments

Comments
 (0)