Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 77ba257

Browse files
committed
Adding WriterTMatcher and WriterT#evalT/execT
1 parent 0ef288e commit 77ba257

File tree

3 files changed

+134
-17
lines changed

3 files changed

+134
-17
lines changed

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,37 @@ private WriterT(Fn1<? super Monoid<W>, ? extends MonadRec<Tuple2<A, W>, M>> writ
4646
* accumulation and the result inside the {@link Monad}.
4747
*
4848
* @param monoid the accumulation {@link Monoid}
49-
* @param <MAW> the inferred {@link Monad} result
49+
* @param <MAW> the inferred {@link MonadRec} result
5050
* @return the accumulation with the result
5151
*/
5252
public <MAW extends MonadRec<Tuple2<A, W>, M>> MAW runWriterT(Monoid<W> monoid) {
5353
return writerFn.apply(monoid).coerce();
5454
}
5555

56+
/**
57+
* Given a {@link Monoid} for the accumulation, run the computation represented by this {@link WriterT} inside the
58+
* {@link Monad monadic effect}, ignoring the resulting accumulation, yielding the value in isolation.
59+
*
60+
* @param monoid the accumulation {@link Monoid}
61+
* @param <MA> the inferred {@link MonadRec} result
62+
* @return the result
63+
*/
64+
public <MA extends MonadRec<A, M>> MA evalWriterT(Monoid<W> monoid) {
65+
return runWriterT(monoid).fmap(Tuple2::_1).coerce();
66+
}
67+
68+
/**
69+
* Given a {@link Monoid} for the accumulation, run the computation represented by this {@link WriterT} inside the
70+
* {@link Monad monadic effect}, ignoring the value, yielding the accumulation in isolation.
71+
*
72+
* @param monoid the accumulation {@link Monoid}
73+
* @param <MW> the inferred {@link MonadRec} accumulation
74+
* @return the accumulation
75+
*/
76+
public <MW extends MonadRec<W, M>> MW execWriterT(Monoid<W> monoid) {
77+
return runWriterT(monoid).fmap(Tuple2::_2).coerce();
78+
}
79+
5680
/**
5781
* {@inheritDoc}
5882
*/

src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/WriterTTest.java

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@
2525
import static com.jnape.palatable.lambda.monad.transformer.builtin.WriterT.writerT;
2626
import static com.jnape.palatable.lambda.monoid.builtin.Join.join;
2727
import static com.jnape.palatable.lambda.monoid.builtin.Trivial.trivial;
28-
import static org.junit.Assert.assertEquals;
28+
import static org.hamcrest.core.IsEqual.equalTo;
29+
import static org.junit.Assert.assertThat;
30+
import static testsupport.matchers.WriterTMatcher.whenEvaluatedWith;
31+
import static testsupport.matchers.WriterTMatcher.whenExecutedWith;
32+
import static testsupport.matchers.WriterTMatcher.whenRunWith;
2933
import static testsupport.traits.Equivalence.equivalence;
3034

3135
@RunWith(Traits.class)
@@ -38,38 +42,46 @@ public Equivalence<WriterT<String, Identity<?>, Integer>> testSubject() {
3842

3943
@Test
4044
public void accumulationUsesProvidedMonoid() {
41-
Identity<Tuple2<Integer, String>> result = writerT(new Identity<>(tuple(1, "foo")))
42-
.discardR(WriterT.tell(new Identity<>("bar")))
43-
.flatMap(x -> writerT(new Identity<>(tuple(x + 1, "baz"))))
44-
.runWriterT(join());
45+
assertThat(writerT(new Identity<>(tuple(1, "foo")))
46+
.discardR(WriterT.tell(new Identity<>("bar")))
47+
.flatMap(x -> writerT(new Identity<>(tuple(x + 1, "baz")))),
48+
whenRunWith(join(), equalTo(new Identity<>(tuple(2, "foobarbaz")))));
49+
}
4550

46-
assertEquals(new Identity<>(tuple(2, "foobarbaz")), result);
51+
@Test
52+
public void eval() {
53+
assertThat(writerT(new Identity<>(tuple(1, "foo"))),
54+
whenEvaluatedWith(join(), equalTo(new Identity<>(1))));
55+
}
56+
57+
@Test
58+
public void exec() {
59+
assertThat(writerT(new Identity<>(tuple(1, "foo"))),
60+
whenExecutedWith(join(), equalTo(new Identity<>("foo"))));
4761
}
4862

4963
@Test
5064
public void tell() {
51-
assertEquals(new Identity<>(tuple(UNIT, "")),
52-
WriterT.tell(new Identity<>("")).runWriterT(join()));
65+
assertThat(WriterT.tell(new Identity<>("")),
66+
whenRunWith(join(), equalTo(new Identity<>(tuple(UNIT, "")))));
5367
}
5468

5569
@Test
5670
public void listen() {
57-
assertEquals(new Identity<>(tuple(1, "")),
58-
WriterT.<String, Identity<?>, Integer>listen(new Identity<>(1)).runWriterT(join()));
71+
assertThat(WriterT.listen(new Identity<>(1)),
72+
whenRunWith(join(), equalTo(new Identity<>(tuple(1, "")))));
5973
}
6074

6175
@Test
6276
public void staticPure() {
63-
WriterT<String, Identity<?>, Integer> apply = WriterT.<String, Identity<?>>pureWriterT(pureIdentity()).apply(1);
64-
assertEquals(new Identity<>(tuple(1, "")),
65-
apply.runWriterT(join()));
77+
assertThat(WriterT.<String, Identity<?>>pureWriterT(pureIdentity()).apply(1),
78+
whenRunWith(join(), equalTo(new Identity<>(tuple(1, "")))));
6679
}
6780

6881
@Test
6982
public void staticLift() {
70-
WriterT<String, Identity<?>, Integer> apply = WriterT.<String>liftWriterT().apply(new Identity<>(1));
71-
assertEquals(new Identity<>(tuple(1, "")),
72-
apply.runWriterT(join()));
83+
assertThat(WriterT.<String>liftWriterT().apply(new Identity<>(1)),
84+
whenRunWith(join(), equalTo(new Identity<>(tuple(1, "")))));
7385
}
7486

7587
@Test(timeout = 500)
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package testsupport.matchers;
2+
3+
import com.jnape.palatable.lambda.adt.hlist.Tuple2;
4+
import com.jnape.palatable.lambda.monad.MonadRec;
5+
import com.jnape.palatable.lambda.monad.transformer.builtin.WriterT;
6+
import com.jnape.palatable.lambda.monoid.Monoid;
7+
import org.hamcrest.Description;
8+
import org.hamcrest.Matcher;
9+
import org.hamcrest.TypeSafeMatcher;
10+
11+
public final class WriterTMatcher<W, M extends MonadRec<?, M>, A> extends
12+
TypeSafeMatcher<MonadRec<A, WriterT<W, M, ?>>> {
13+
14+
private final Matcher<? extends MonadRec<Tuple2<A, W>, M>> expected;
15+
private final Monoid<W> wMonoid;
16+
17+
private WriterTMatcher(Matcher<? extends MonadRec<Tuple2<A, W>, M>> expected, Monoid<W> wMonoid) {
18+
this.wMonoid = wMonoid;
19+
this.expected = expected;
20+
}
21+
22+
@Override
23+
protected boolean matchesSafely(MonadRec<A, WriterT<W, M, ?>> item) {
24+
return expected.matches(item.<WriterT<W, M, A>>coerce().runWriterT(wMonoid));
25+
}
26+
27+
@Override
28+
public void describeTo(Description description) {
29+
expected.describeTo(description);
30+
}
31+
32+
@Override
33+
protected void describeMismatchSafely(MonadRec<A, WriterT<W, M, ?>> item, Description mismatchDescription) {
34+
expected.describeMismatch(item.<WriterT<W, M, A>>coerce().runWriterT(wMonoid), mismatchDescription);
35+
}
36+
37+
public static <W, M extends MonadRec<?, M>, A, MAW extends MonadRec<Tuple2<A, W>, M>>
38+
WriterTMatcher<W, M, A> whenRunWith(Monoid<W> wMonoid, Matcher<MAW> matcher) {
39+
return new WriterTMatcher<>(matcher, wMonoid);
40+
}
41+
42+
public static <W, M extends MonadRec<?, M>, A, MW extends MonadRec<? extends W, M>>
43+
WriterTMatcher<W, M, A> whenExecutedWith(Monoid<W> wMonoid, Matcher<MW> matcher) {
44+
return whenRunWith(wMonoid, new TypeSafeMatcher<MonadRec<Tuple2<A, W>, M>>() {
45+
@Override
46+
protected boolean matchesSafely(MonadRec<Tuple2<A, W>, M> item) {
47+
return matcher.matches(item.fmap(Tuple2::_2));
48+
}
49+
50+
@Override
51+
public void describeTo(Description description) {
52+
matcher.describeTo(description);
53+
}
54+
55+
@Override
56+
protected void describeMismatchSafely(MonadRec<Tuple2<A, W>, M> item, Description mismatchDescription) {
57+
matcher.describeMismatch(item.fmap(Tuple2::_2), mismatchDescription);
58+
}
59+
});
60+
}
61+
62+
public static <W, M extends MonadRec<?, M>, A, MA extends MonadRec<A, M>>
63+
WriterTMatcher<W, M, A> whenEvaluatedWith(Monoid<W> wMonoid, Matcher<MA> matcher) {
64+
return whenRunWith(wMonoid, new TypeSafeMatcher<MonadRec<Tuple2<A, W>, M>>() {
65+
@Override
66+
protected boolean matchesSafely(MonadRec<Tuple2<A, W>, M> item) {
67+
return matcher.matches(item.fmap(Tuple2::_1));
68+
}
69+
70+
@Override
71+
public void describeTo(Description description) {
72+
matcher.describeTo(description);
73+
}
74+
75+
@Override
76+
protected void describeMismatchSafely(MonadRec<Tuple2<A, W>, M> item, Description mismatchDescription) {
77+
matcher.describeMismatch(item.fmap(Tuple2::_1), mismatchDescription);
78+
}
79+
});
80+
}
81+
}

0 commit comments

Comments
 (0)