Skip to content

Commit eca9d40

Browse files
committed
- WriterT#pure now has direct access to embedded monad's pure
- EitherMatcher#isLeftOf/isRightOf for equality matching - updating CHANGELOG
1 parent 31ad726 commit eca9d40

File tree

3 files changed

+32
-11
lines changed

3 files changed

+32
-11
lines changed

CHANGELOG.md

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11
# Change Log
2+
23
All notable changes to this project will be documented in this file.
34

45
The format is based on [Keep a Changelog](http://keepachangelog.com/).
56

67
## [Unreleased]
78

9+
### Changed
10+
- `Absent` folds short-circuit on the first `nothing()`
11+
- `EitherMatcher#isLeftThat/isRightThat` support contravariant bounds on their delegates
12+
813
### Added
14+
- `IterateT#runStep`, a method used to run a single step of an IterateT without the contractual guarantee of emitting a
15+
value or reaching the end
16+
- `These#fromMaybes :: Maybe a -> Maybe b -> Maybe (These a b)`
17+
- `EitherMatcher#isLeftOf/isRightOf` for asserting equality
918

10-
- `IterateT#runStep`, a method used to run a single step of an IterateT without the contractual
11-
guarantee of emitting a value or reaching the end
19+
### Fixed
20+
- `WriterT` now keeps an immediate reference to the embedded monad's `pure`
1221

1322
## [5.3.0] - 2020-12-07
1423

src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/WriterT.java

+12-9
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,12 @@ public final class WriterT<W, M extends MonadRec<?, M>, A> implements
3434
MonadWriter<W, A, WriterT<W, M, ?>>,
3535
MonadT<M, A, WriterT<W, M, ?>, WriterT<W, ?, ?>> {
3636

37+
private final Pure<M> pureM;
3738
private final Fn1<? super Monoid<W>, ? extends MonadRec<Tuple2<A, W>, M>> writerFn;
3839

39-
private WriterT(Fn1<? super Monoid<W>, ? extends MonadRec<Tuple2<A, W>, M>> writerFn) {
40+
private WriterT(Pure<M> pureM,
41+
Fn1<? super Monoid<W>, ? extends MonadRec<Tuple2<A, W>, M>> writerFn) {
42+
this.pureM = pureM;
4043
this.writerFn = writerFn;
4144
}
4245

@@ -82,15 +85,15 @@ public <MW extends MonadRec<W, M>> MW execWriterT(Monoid<W> monoid) {
8285
*/
8386
@Override
8487
public <B> WriterT<W, M, Tuple2<A, B>> listens(Fn1<? super W, ? extends B> fn) {
85-
return new WriterT<>(writerFn.fmap(m -> m.fmap(into((a, w) -> both(both(constantly(a), fn), id(), w)))));
88+
return new WriterT<>(pureM, writerFn.fmap(m -> m.fmap(into((a, w) -> both(both(constantly(a), fn), id(), w)))));
8689
}
8790

8891
/**
8992
* {@inheritDoc}
9093
*/
9194
@Override
9295
public WriterT<W, M, A> censor(Fn1<? super W, ? extends W> fn) {
93-
return new WriterT<>(writerFn.fmap(mt -> mt.fmap(t -> t.fmap(fn))));
96+
return new WriterT<>(pureM, writerFn.fmap(mt -> mt.fmap(t -> t.fmap(fn))));
9497
}
9598

9699
/**
@@ -107,7 +110,7 @@ public <B, N extends MonadRec<?, N>> WriterT<W, N, B> lift(MonadRec<B, N> mb) {
107110
@Override
108111
public <B> WriterT<W, M, B> trampolineM(
109112
Fn1<? super A, ? extends MonadRec<RecursiveResult<A, B>, WriterT<W, M, ?>>> fn) {
110-
return new WriterT<>(monoid -> runWriterT(monoid).trampolineM(into((a, w) -> fn.apply(a)
113+
return new WriterT<>(pureM, monoid -> runWriterT(monoid).trampolineM(into((a, w) -> fn.apply(a)
111114
.<WriterT<W, M, RecursiveResult<A, B>>>coerce()
112115
.runWriterT(monoid).fmap(t -> t.fmap(monoid.apply(w)))
113116
.fmap(into((aOrB, w_) -> aOrB.biMap(a_ -> tuple(a_, w_), b -> tuple(b, w_)))))));
@@ -126,15 +129,15 @@ public <B> WriterT<W, M, B> fmap(Fn1<? super A, ? extends B> fn) {
126129
*/
127130
@Override
128131
public <B> WriterT<W, M, B> pure(B b) {
129-
return new WriterT<>(m -> runWriterT(m).pure(tuple(b, m.identity())));
132+
return new WriterT<>(pureM, m -> pureM.apply(tuple(b, m.identity())));
130133
}
131134

132135
/**
133136
* {@inheritDoc}
134137
*/
135138
@Override
136139
public <B> WriterT<W, M, B> flatMap(Fn1<? super A, ? extends Monad<B, WriterT<W, M, ?>>> f) {
137-
return new WriterT<>(monoid -> writerFn.apply(monoid)
140+
return new WriterT<>(pureM, monoid -> writerFn.apply(monoid)
138141
.flatMap(into((a, w) -> f.apply(a).<WriterT<W, M, B>>coerce().runWriterT(monoid)
139142
.fmap(t -> t.fmap(monoid.apply(w))))));
140143
}
@@ -144,7 +147,7 @@ public <B> WriterT<W, M, B> flatMap(Fn1<? super A, ? extends Monad<B, WriterT<W,
144147
*/
145148
@Override
146149
public <B> WriterT<W, M, B> zip(Applicative<Fn1<? super A, ? extends B>, WriterT<W, M, ?>> appFn) {
147-
return new WriterT<>(monoid -> runWriterT(monoid)
150+
return new WriterT<>(pureM, monoid -> runWriterT(monoid)
148151
.zip(appFn.<WriterT<W, M, Fn1<? super A, ? extends B>>>coerce().runWriterT(monoid)
149152
.fmap(into((f, y) -> into((a, x) -> tuple(f.apply(a), monoid.apply(x, y)))))));
150153
}
@@ -196,7 +199,7 @@ public static <W, M extends MonadRec<?, M>> WriterT<W, M, Unit> tell(MonadRec<W,
196199
* @return the {@link WriterT}
197200
*/
198201
public static <W, M extends MonadRec<?, M>, A> WriterT<W, M, A> listen(MonadRec<A, M> ma) {
199-
return new WriterT<>(monoid -> ma.fmap(a -> tuple(a, monoid.identity())));
202+
return new WriterT<>(Pure.of(ma), monoid -> ma.fmap(a -> tuple(a, monoid.identity())));
200203
}
201204

202205
/**
@@ -209,7 +212,7 @@ public static <W, M extends MonadRec<?, M>, A> WriterT<W, M, A> listen(MonadRec<
209212
* @return the {@link WriterT}
210213
*/
211214
public static <W, M extends MonadRec<?, M>, A> WriterT<W, M, A> writerT(MonadRec<Tuple2<A, W>, M> maw) {
212-
return new WriterT<>(constantly(maw));
215+
return new WriterT<>(Pure.of(maw), constantly(maw));
213216
}
214217

215218
/**

src/test/java/testsupport/matchers/EitherMatcher.java

+9
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
1111
import static com.jnape.palatable.lambda.io.IO.io;
1212
import static org.hamcrest.CoreMatchers.anything;
13+
import static org.hamcrest.CoreMatchers.equalTo;
1314

1415
public final class EitherMatcher<L, R> extends TypeSafeMatcher<Either<L, R>> {
1516
private final Either<Matcher<? super L>, Matcher<? super R>> matcher;
@@ -53,11 +54,19 @@ public static <L, R> EitherMatcher<L, R> isLeft() {
5354
return isLeftThat(anything());
5455
}
5556

57+
public static <L, R> EitherMatcher<L, R> isLeftOf(L l) {
58+
return isLeftThat(equalTo(l));
59+
}
60+
5661
public static <L, R> EitherMatcher<L, R> isRightThat(Matcher<? super R> rMatcher) {
5762
return new EitherMatcher<>(right(rMatcher));
5863
}
5964

6065
public static <L, R> EitherMatcher<L, R> isRight() {
6166
return isRightThat(anything());
6267
}
68+
69+
public static <L, R> EitherMatcher<L, R> isRightOf(R r) {
70+
return isRightThat(equalTo(r));
71+
}
6372
}

0 commit comments

Comments
 (0)