Skip to content

Commit a5d81ee

Browse files
committed
MonadError, monads that can be thrown to and caught from
- Either - IO - Try - Maybe
1 parent 02d0d7d commit a5d81ee

File tree

15 files changed

+374
-91
lines changed

15 files changed

+374
-91
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
2222
- `IO#pin`, for pinning an `IO` to an `Executor` without yet executing it
2323
- `IO#fuse`, for fusing the fork opportunities of a given `IO` into a single linearized `IO`
2424
- `IO#exceptionallyIO`, like `exceptionally` but recover inside another `IO`
25+
- `MonadError`, monads that can be thrown to and caught from
2526

2627
## [4.0.0] - 2019-05-20
2728
### Changed

pom.xml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
34
<modelVersion>4.0.0</modelVersion>
45

56
<parent>
@@ -60,6 +61,12 @@
6061
</properties>
6162

6263
<dependencies>
64+
<dependency>
65+
<groupId>io.jaegertracing</groupId>
66+
<artifactId>jaeger-client</artifactId>
67+
<version>0.35.5</version>
68+
<scope>test</scope>
69+
</dependency>
6370
<dependency>
6471
<groupId>junit</groupId>
6572
<artifactId>junit</artifactId>

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

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.jnape.palatable.lambda.functor.builtin.Lazy;
1414
import com.jnape.palatable.lambda.io.IO;
1515
import com.jnape.palatable.lambda.monad.Monad;
16+
import com.jnape.palatable.lambda.monad.MonadError;
1617
import com.jnape.palatable.lambda.traversable.Traversable;
1718

1819
import java.util.Objects;
@@ -32,7 +33,7 @@
3233
*/
3334
public abstract class Either<L, R> implements
3435
CoProduct2<L, R, Either<L, R>>,
35-
Monad<R, Either<L, ?>>,
36+
MonadError<L, R, Either<L, ?>>,
3637
Traversable<R, Either<L, ?>>,
3738
Bifunctor<L, R, Either<?, ?>> {
3839

@@ -206,7 +207,7 @@ public <C> Choice3<L, R, C> diverge() {
206207
*/
207208
@Override
208209
public final <R2> Either<L, R2> fmap(Fn1<? super R, ? extends R2> fn) {
209-
return Monad.super.<R2>fmap(fn).coerce();
210+
return MonadError.super.<R2>fmap(fn).coerce();
210211
}
211212

212213
/**
@@ -247,7 +248,7 @@ public final <R2> Either<L, R2> pure(R2 r2) {
247248
*/
248249
@Override
249250
public final <R2> Either<L, R2> zip(Applicative<Fn1<? super R, ? extends R2>, Either<L, ?>> appFn) {
250-
return Monad.super.zip(appFn).coerce();
251+
return MonadError.super.zip(appFn).coerce();
251252
}
252253

253254
/**
@@ -265,15 +266,31 @@ public <R2> Lazy<Either<L, R2>> lazyZip(
265266
*/
266267
@Override
267268
public final <R2> Either<L, R2> discardL(Applicative<R2, Either<L, ?>> appB) {
268-
return Monad.super.discardL(appB).coerce();
269+
return MonadError.super.discardL(appB).coerce();
269270
}
270271

271272
/**
272273
* {@inheritDoc}
273274
*/
274275
@Override
275276
public final <R2> Either<L, R> discardR(Applicative<R2, Either<L, ?>> appB) {
276-
return Monad.super.discardR(appB).coerce();
277+
return MonadError.super.discardR(appB).coerce();
278+
}
279+
280+
/**
281+
* {@inheritDoc}
282+
*/
283+
@Override
284+
public Either<L, R> throwError(L l) {
285+
return left(l);
286+
}
287+
288+
/**
289+
* {@inheritDoc}
290+
*/
291+
@Override
292+
public Either<L, R> catchError(Fn1<? super L, ? extends Monad<R, Either<L, ?>>> recoveryFn) {
293+
return match(recoveryFn.fmap(Monad::coerce), Either::right);
277294
}
278295

279296
/**

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

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.jnape.palatable.lambda.functor.builtin.Lazy;
1414
import com.jnape.palatable.lambda.io.IO;
1515
import com.jnape.palatable.lambda.monad.Monad;
16+
import com.jnape.palatable.lambda.monad.MonadError;
1617
import com.jnape.palatable.lambda.traversable.Traversable;
1718

1819
import java.util.Objects;
@@ -34,7 +35,7 @@
3435
*/
3536
public abstract class Maybe<A> implements
3637
CoProduct2<Unit, A, Maybe<A>>,
37-
Monad<A, Maybe<?>>,
38+
MonadError<Unit, A, Maybe<?>>,
3839
Traversable<A, Maybe<?>> {
3940

4041
private Maybe() {
@@ -86,6 +87,22 @@ public final Maybe<A> filter(Fn1<? super A, ? extends Boolean> predicate) {
8687
return flatMap(a -> predicate.apply(a) ? just(a) : nothing());
8788
}
8889

90+
/**
91+
* {@inheritDoc}
92+
*/
93+
@Override
94+
public Maybe<A> throwError(Unit unit) {
95+
return nothing();
96+
}
97+
98+
/**
99+
* {@inheritDoc}
100+
*/
101+
@Override
102+
public Maybe<A> catchError(Fn1<? super Unit, ? extends Monad<A, Maybe<?>>> recoveryFn) {
103+
return match(recoveryFn, Maybe::just).coerce();
104+
}
105+
89106
/**
90107
* If this value is absent, return the value supplied by <code>lSupplier</code> wrapped in <code>Either.left</code>.
91108
* Otherwise, wrap the value in <code>Either.right</code> and return it.
@@ -127,15 +144,15 @@ public final <B> Maybe<B> pure(B b) {
127144
*/
128145
@Override
129146
public final <B> Maybe<B> fmap(Fn1<? super A, ? extends B> fn) {
130-
return Monad.super.<B>fmap(fn).coerce();
147+
return MonadError.super.<B>fmap(fn).coerce();
131148
}
132149

133150
/**
134151
* {@inheritDoc}
135152
*/
136153
@Override
137154
public final <B> Maybe<B> zip(Applicative<Fn1<? super A, ? extends B>, Maybe<?>> appFn) {
138-
return Monad.super.zip(appFn).coerce();
155+
return MonadError.super.zip(appFn).coerce();
139156
}
140157

141158
/**
@@ -156,15 +173,15 @@ public <B> Lazy<Maybe<B>> lazyZip(Lazy<? extends Applicative<Fn1<? super A, ? ex
156173
*/
157174
@Override
158175
public final <B> Maybe<B> discardL(Applicative<B, Maybe<?>> appB) {
159-
return Monad.super.discardL(appB).coerce();
176+
return MonadError.super.discardL(appB).coerce();
160177
}
161178

162179
/**
163180
* {@inheritDoc}
164181
*/
165182
@Override
166183
public final <B> Maybe<A> discardR(Applicative<B, Maybe<?>> appB) {
167-
return Monad.super.discardR(appB).coerce();
184+
return MonadError.super.discardR(appB).coerce();
168185
}
169186

170187
/**

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

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.jnape.palatable.lambda.functor.builtin.Lazy;
99
import com.jnape.palatable.lambda.io.IO;
1010
import com.jnape.palatable.lambda.monad.Monad;
11+
import com.jnape.palatable.lambda.monad.MonadError;
1112
import com.jnape.palatable.lambda.traversable.Traversable;
1213

1314
import java.util.Objects;
@@ -27,7 +28,10 @@
2728
* @param <A> the possibly successful expression result
2829
* @see Either
2930
*/
30-
public abstract class Try<A> implements Monad<A, Try<?>>, Traversable<A, Try<?>>, CoProduct2<Throwable, A, Try<A>> {
31+
public abstract class Try<A> implements
32+
MonadError<Throwable, A, Try<?>>,
33+
Traversable<A, Try<?>>,
34+
CoProduct2<Throwable, A, Try<A>> {
3135

3236
private Try() {
3337
}
@@ -162,12 +166,28 @@ public final <L> Either<L, A> toEither(Fn1<? super Throwable, ? extends L> fn) {
162166
return match(fn.fmap(Either::left), Either::right);
163167
}
164168

169+
/**
170+
* {@inheritDoc}
171+
*/
172+
@Override
173+
public Try<A> throwError(Throwable throwable) {
174+
return failure(throwable);
175+
}
176+
177+
/**
178+
* {@inheritDoc}
179+
*/
180+
@Override
181+
public Try<A> catchError(Fn1<? super Throwable, ? extends Monad<A, Try<?>>> recoveryFn) {
182+
return match(t -> recoveryFn.apply(t).coerce(), Try::success);
183+
}
184+
165185
/**
166186
* {@inheritDoc}
167187
*/
168188
@Override
169189
public <B> Try<B> fmap(Fn1<? super A, ? extends B> fn) {
170-
return Monad.super.<B>fmap(fn).coerce();
190+
return MonadError.super.<B>fmap(fn).coerce();
171191
}
172192

173193
/**
@@ -191,7 +211,7 @@ public <B> Try<B> pure(B b) {
191211
*/
192212
@Override
193213
public <B> Try<B> zip(Applicative<Fn1<? super A, ? extends B>, Try<?>> appFn) {
194-
return Monad.super.zip(appFn).coerce();
214+
return MonadError.super.zip(appFn).coerce();
195215
}
196216

197217
/**
@@ -208,15 +228,15 @@ public <B> Lazy<Try<B>> lazyZip(Lazy<? extends Applicative<Fn1<? super A, ? exte
208228
*/
209229
@Override
210230
public <B> Try<B> discardL(Applicative<B, Try<?>> appB) {
211-
return Monad.super.discardL(appB).coerce();
231+
return MonadError.super.discardL(appB).coerce();
212232
}
213233

214234
/**
215235
* {@inheritDoc}
216236
*/
217237
@Override
218238
public <B> Try<A> discardR(Applicative<B, Try<?>> appB) {
219-
return Monad.super.discardR(appB).coerce();
239+
return MonadError.super.discardR(appB).coerce();
220240
}
221241

222242
/**

0 commit comments

Comments
 (0)