1818import com .jnape .palatable .lambda .monad .MonadRec ;
1919import com .jnape .palatable .lambda .traversable .Traversable ;
2020
21- import java .util .Objects ;
2221import java .util .Optional ;
2322
2423import static com .jnape .palatable .lambda .adt .Either .left ;
3837 * @param <A> the optional parameter type
3938 * @see Optional
4039 */
41- public abstract class Maybe <A > implements
40+ public sealed interface Maybe <A > extends
4241 CoProduct2 <Unit , A , Maybe <A >>,
4342 MonadError <Unit , A , Maybe <?>>,
4443 MonadRec <A , Maybe <?>>,
45- Traversable <A , Maybe <?>> {
44+ Traversable <A , Maybe <?>> permits Just , Nothing {
4645
47- private Maybe () {
48- }
4946
5047 /**
5148 * If the value is present, return it; otherwise, return the value supplied by <code>otherSupplier</code>.
5249 *
5350 * @param otherFn0 the supplier for the other value
5451 * @return this value, or the supplied other value
5552 */
56- public final A orElseGet (Fn0 <A > otherFn0 ) {
53+ default A orElseGet (Fn0 <A > otherFn0 ) {
5754 return match (__ -> otherFn0 .apply (), id ());
5855 }
5956
@@ -63,7 +60,7 @@ public final A orElseGet(Fn0<A> otherFn0) {
6360 * @param other the other value
6461 * @return this value, or the other value
6562 */
66- public final A orElse (A other ) {
63+ default A orElse (A other ) {
6764 return orElseGet (() -> other );
6865 }
6966
@@ -76,7 +73,7 @@ public final A orElse(A other) {
7673 * @return the value, if present
7774 * @throws E the throwable, if the value is absent
7875 */
79- public final <E extends Throwable > A orElseThrow (Fn0 <? extends E > throwableSupplier ) throws E {
76+ default <E extends Throwable > A orElseThrow (Fn0 <? extends E > throwableSupplier ) throws E {
8077 return orElseGet (fn0 (() -> {
8178 throw throwableSupplier .apply ();
8279 }));
@@ -89,23 +86,23 @@ public final <E extends Throwable> A orElseThrow(Fn0<? extends E> throwableSuppl
8986 * @param predicate the predicate to apply to the possibly absent value
9087 * @return maybe the present value that satisfied the predicate
9188 */
92- public final Maybe <A > filter (Fn1 <? super A , ? extends Boolean > predicate ) {
89+ default Maybe <A > filter (Fn1 <? super A , ? extends Boolean > predicate ) {
9390 return flatMap (a -> predicate .apply (a ) ? just (a ) : nothing ());
9491 }
9592
9693 /**
9794 * {@inheritDoc}
9895 */
9996 @ Override
100- public Maybe <A > throwError (Unit unit ) {
97+ default Maybe <A > throwError (Unit unit ) {
10198 return nothing ();
10299 }
103100
104101 /**
105102 * {@inheritDoc}
106103 */
107104 @ Override
108- public Maybe <A > catchError (Fn1 <? super Unit , ? extends Monad <A , Maybe <?>>> recoveryFn ) {
105+ default Maybe <A > catchError (Fn1 <? super Unit , ? extends Monad <A , Maybe <?>>> recoveryFn ) {
109106 return match (recoveryFn , Maybe ::just ).coerce ();
110107 }
111108
@@ -117,7 +114,7 @@ public Maybe<A> catchError(Fn1<? super Unit, ? extends Monad<A, Maybe<?>>> recov
117114 * @param lFn0 the supplier for the left value
118115 * @return this value wrapped in an Either.right, or an Either.left around the result of lSupplier
119116 */
120- public final <L > Either <L , A > toEither (Fn0 <L > lFn0 ) {
117+ default <L > Either <L , A > toEither (Fn0 <L > lFn0 ) {
121118 return fmap (Either ::<L , A >right ).orElseGet (() -> left (lFn0 .apply ()));
122119 }
123120
@@ -126,7 +123,7 @@ public final <L> Either<L, A> toEither(Fn0<L> lFn0) {
126123 *
127124 * @return the Optional
128125 */
129- public final Optional <A > toOptional () {
126+ default Optional <A > toOptional () {
130127 return fmap (Optional ::of ).orElseGet (Optional ::empty );
131128 }
132129
@@ -138,7 +135,7 @@ public final Optional<A> toOptional() {
138135 * @return Just b
139136 */
140137 @ Override
141- public final <B > Maybe <B > pure (B b ) {
138+ default <B > Maybe <B > pure (B b ) {
142139 return just (b );
143140 }
144141
@@ -149,15 +146,15 @@ public final <B> Maybe<B> pure(B b) {
149146 * {@link Maybe#nothing}.
150147 */
151148 @ Override
152- public final <B > Maybe <B > fmap (Fn1 <? super A , ? extends B > fn ) {
149+ default <B > Maybe <B > fmap (Fn1 <? super A , ? extends B > fn ) {
153150 return MonadError .super .<B >fmap (fn ).coerce ();
154151 }
155152
156153 /**
157154 * {@inheritDoc}
158155 */
159156 @ Override
160- public final <B > Maybe <B > zip (Applicative <Fn1 <? super A , ? extends B >, Maybe <?>> appFn ) {
157+ default <B > Maybe <B > zip (Applicative <Fn1 <? super A , ? extends B >, Maybe <?>> appFn ) {
161158 return MonadError .super .zip (appFn ).coerce ();
162159 }
163160
@@ -169,7 +166,7 @@ public final <B> Maybe<B> zip(Applicative<Fn1<? super A, ? extends B>, Maybe<?>>
169166 * @return the zipped {@link Maybe}
170167 */
171168 @ Override
172- public <B > Lazy <Maybe <B >> lazyZip (Lazy <? extends Applicative <Fn1 <? super A , ? extends B >, Maybe <?>>> lazyAppFn ) {
169+ default <B > Lazy <Maybe <B >> lazyZip (Lazy <? extends Applicative <Fn1 <? super A , ? extends B >, Maybe <?>>> lazyAppFn ) {
173170 return match (constantly (lazy (nothing ())),
174171 a -> lazyAppFn .fmap (maybeF -> maybeF .<B >fmap (f -> f .apply (a )).coerce ()));
175172 }
@@ -178,15 +175,15 @@ public <B> Lazy<Maybe<B>> lazyZip(Lazy<? extends Applicative<Fn1<? super A, ? ex
178175 * {@inheritDoc}
179176 */
180177 @ Override
181- public final <B > Maybe <B > discardL (Applicative <B , Maybe <?>> appB ) {
178+ default <B > Maybe <B > discardL (Applicative <B , Maybe <?>> appB ) {
182179 return MonadError .super .discardL (appB ).coerce ();
183180 }
184181
185182 /**
186183 * {@inheritDoc}
187184 */
188185 @ Override
189- public final <B > Maybe <A > discardR (Applicative <B , Maybe <?>> appB ) {
186+ default <B > Maybe <A > discardR (Applicative <B , Maybe <?>> appB ) {
190187 return MonadError .super .discardR (appB ).coerce ();
191188 }
192189
@@ -195,15 +192,15 @@ public final <B> Maybe<A> discardR(Applicative<B, Maybe<?>> appB) {
195192 */
196193 @ SuppressWarnings ("RedundantTypeArguments" )
197194 @ Override
198- public final <B > Maybe <B > flatMap (Fn1 <? super A , ? extends Monad <B , Maybe <?>>> f ) {
195+ default <B > Maybe <B > flatMap (Fn1 <? super A , ? extends Monad <B , Maybe <?>>> f ) {
199196 return match (constantly (nothing ()), f .fmap (Monad <B , Maybe <?>>::coerce ));
200197 }
201198
202199 /**
203200 * {@inheritDoc}
204201 */
205202 @ Override
206- public <B > Maybe <B > trampolineM (Fn1 <? super A , ? extends MonadRec <RecursiveResult <A , B >, Maybe <?>>> fn ) {
203+ default <B > Maybe <B > trampolineM (Fn1 <? super A , ? extends MonadRec <RecursiveResult <A , B >, Maybe <?>>> fn ) {
207204 return match (constantly (nothing ()), trampoline (a -> fn .apply (a ).<Maybe <RecursiveResult <A , B >>>coerce ()
208205 .match (constantly (terminate (nothing ())),
209206 aOrB -> aOrB .fmap (Maybe ::just ))));
@@ -213,23 +210,23 @@ public <B> Maybe<B> trampolineM(Fn1<? super A, ? extends MonadRec<RecursiveResul
213210 * {@inheritDoc}
214211 */
215212 @ Override
216- public <B > Choice3 <Unit , A , B > diverge () {
213+ default <B > Choice3 <Unit , A , B > diverge () {
217214 return match (Choice3 ::a , Choice3 ::b );
218215 }
219216
220217 /**
221218 * {@inheritDoc}
222219 */
223220 @ Override
224- public Tuple2 <Maybe <Unit >, Maybe <A >> project () {
221+ default Tuple2 <Maybe <Unit >, Maybe <A >> project () {
225222 return CoProduct2 .super .project ().into (HList ::tuple );
226223 }
227224
228225 /**
229226 * {@inheritDoc}
230227 */
231228 @ Override
232- public Choice2 <A , Unit > invert () {
229+ default Choice2 <A , Unit > invert () {
233230 return match (Choice2 ::b , Choice2 ::a );
234231 }
235232
@@ -241,13 +238,13 @@ public Choice2<A, Unit> invert() {
241238 * @deprecated in favor of {@link Maybe#match(Fn1, Fn1) matching} into an {@link IO} and explicitly running it
242239 */
243240 @ Deprecated
244- public final Maybe <A > peek (Fn1 <? super A , ? extends IO <?>> effect ) {
241+ default Maybe <A > peek (Fn1 <? super A , ? extends IO <?>> effect ) {
245242 return match (constantly (io (this )), a -> effect .apply (a ).fmap (constantly (this ))).unsafePerformIO ();
246243 }
247244
248245 @ Override
249246 @ SuppressWarnings ("unchecked" )
250- public final <B , App extends Applicative <?, App >, TravB extends Traversable <B , Maybe <?>>,
247+ default <B , App extends Applicative <?, App >, TravB extends Traversable <B , Maybe <?>>,
251248 AppTrav extends Applicative <TravB , App >> AppTrav traverse (Fn1 <? super A , ? extends Applicative <B , App >> fn ,
252249 Fn1 <? super TravB , ? extends AppTrav > pure ) {
253250 return match (__ -> pure .apply ((TravB ) Maybe .<B >nothing ()), a -> (AppTrav ) fn .apply (a ).fmap (Maybe ::just ));
@@ -261,7 +258,7 @@ AppTrav extends Applicative<TravB, App>> AppTrav traverse(Fn1<? super A, ? exten
261258 * @param <A> the potential right value
262259 * @return "Just" the right value, or nothing
263260 */
264- public static <A > Maybe <A > fromEither (Either <?, A > either ) {
261+ static <A > Maybe <A > fromEither (Either <?, A > either ) {
265262 return either .toMaybe ();
266263 }
267264
@@ -272,7 +269,7 @@ public static <A> Maybe<A> fromEither(Either<?, A> either) {
272269 * @param <A> the optional parameter type
273270 * @return the equivalent Maybe instance
274271 */
275- public static <A > Maybe <A > fromOptional (Optional <? extends A > optional ) {
272+ static <A > Maybe <A > fromOptional (Optional <? extends A > optional ) {
276273 return optional .map (Maybe ::<A >just ).orElse (Maybe .nothing ());
277274 }
278275
@@ -284,7 +281,7 @@ public static <A> Maybe<A> fromOptional(Optional<? extends A> optional) {
284281 * @param <A> the value parameter type
285282 * @return "Just" the value, or nothing
286283 */
287- public static <A > Maybe <A > maybe (A a ) {
284+ static <A > Maybe <A > maybe (A a ) {
288285 return a == null ? nothing () : just (a );
289286 }
290287
@@ -297,7 +294,7 @@ public static <A> Maybe<A> maybe(A a) {
297294 * @return "Just" the value
298295 * @throws NullPointerException if a is null
299296 */
300- public static <A > Maybe <A > just (A a ) {
297+ static <A > Maybe <A > just (A a ) {
301298 if (a == null )
302299 throw new NullPointerException ();
303300 return new Just <>(a );
@@ -310,7 +307,7 @@ public static <A> Maybe<A> just(A a) {
310307 * @return nothing
311308 */
312309 @ SuppressWarnings ("unchecked" )
313- public static <A > Maybe <A > nothing () {
310+ static <A > Maybe <A > nothing () {
314311 return (Maybe <A >) Nothing .INSTANCE ;
315312 }
316313
@@ -319,53 +316,22 @@ public static <A> Maybe<A> nothing() {
319316 *
320317 * @return the {@link Pure} instance
321318 */
322- public static Pure <Maybe <?>> pureMaybe () {
319+ static Pure <Maybe <?>> pureMaybe () {
323320 return Maybe ::just ;
324321 }
322+ }
323+ record Nothing <A >() implements Maybe <A > {
324+ static final Nothing <?> INSTANCE = new Nothing <>();
325325
326- private static final class Nothing <A > extends Maybe <A > {
327- private static final Nothing <?> INSTANCE = new Nothing <>();
328-
329- private Nothing () {
330- }
331-
332- @ Override
333- public <R > R match (Fn1 <? super Unit , ? extends R > aFn , Fn1 <? super A , ? extends R > bFn ) {
334- return aFn .apply (UNIT );
335- }
336-
337- @ Override
338- public String toString () {
339- return "Nothing" ;
340- }
326+ @ Override
327+ public <R > R match (Fn1 <? super Unit , ? extends R > aFn , Fn1 <? super A , ? extends R > bFn ) {
328+ return aFn .apply (UNIT );
341329 }
330+ }
342331
343- private static final class Just <A > extends Maybe <A > {
344-
345- private final A a ;
346-
347- private Just (A a ) {
348- this .a = a ;
349- }
350-
351- @ Override
352- public <R > R match (Fn1 <? super Unit , ? extends R > aFn , Fn1 <? super A , ? extends R > bFn ) {
353- return bFn .apply (a );
354- }
355-
356- @ Override
357- public boolean equals (Object other ) {
358- return other instanceof Just && Objects .equals (this .a , ((Just ) other ).a );
359- }
360-
361- @ Override
362- public int hashCode () {
363- return Objects .hash (a );
364- }
365-
366- @ Override
367- public String toString () {
368- return "Just " + a ;
369- }
332+ record Just <A >(A a ) implements Maybe <A > {
333+ @ Override
334+ public <R > R match (Fn1 <? super Unit , ? extends R > aFn , Fn1 <? super A , ? extends R > bFn ) {
335+ return bFn .apply (a );
370336 }
371- }
337+ }
0 commit comments