|
10 | 10 | import testsupport.traits.ApplicativeLaws; |
11 | 11 | import testsupport.traits.FunctorLaws; |
12 | 12 | import testsupport.traits.MonadLaws; |
| 13 | +import testsupport.traits.MonadRecLaws; |
13 | 14 | import testsupport.traits.TraversableLaws; |
14 | 15 |
|
15 | 16 | import static com.jnape.palatable.lambda.adt.Maybe.just; |
|
19 | 20 | import static com.jnape.palatable.lambda.functions.builtin.fn1.Size.size; |
20 | 21 | import static com.jnape.palatable.lambda.functions.builtin.fn2.Cons.cons; |
21 | 22 | import static com.jnape.palatable.lambda.functions.builtin.fn2.Replicate.replicate; |
| 23 | +import static com.jnape.palatable.lambda.functions.recursion.RecursiveResult.recurse; |
| 24 | +import static com.jnape.palatable.lambda.functions.recursion.RecursiveResult.terminate; |
22 | 25 | import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; |
23 | 26 | import static com.jnape.palatable.lambda.traversable.LambdaIterable.empty; |
24 | 27 | import static com.jnape.palatable.lambda.traversable.LambdaIterable.pureLambdaIterable; |
25 | 28 | import static com.jnape.palatable.lambda.traversable.LambdaIterable.wrap; |
26 | 29 | import static com.jnape.palatable.traitor.framework.Subjects.subjects; |
27 | 30 | import static java.util.Arrays.asList; |
28 | 31 | import static java.util.Collections.singleton; |
| 32 | +import static java.util.Collections.singletonList; |
29 | 33 | import static org.junit.Assert.assertEquals; |
30 | 34 | import static org.junit.Assert.assertThat; |
31 | 35 | import static testsupport.Constants.STACK_EXPLODING_NUMBER; |
|
34 | 38 | @RunWith(Traits.class) |
35 | 39 | public class LambdaIterableTest { |
36 | 40 |
|
37 | | - @TestTraits({FunctorLaws.class, ApplicativeLaws.class, TraversableLaws.class, MonadLaws.class}) |
| 41 | + @TestTraits({FunctorLaws.class, ApplicativeLaws.class, TraversableLaws.class, MonadLaws.class, MonadRecLaws.class}) |
38 | 42 | public Subjects<LambdaIterable<Object>> testSubject() { |
39 | 43 | return subjects(LambdaIterable.empty(), wrap(singleton(1)), wrap(replicate(100, 1))); |
40 | 44 | } |
41 | 45 |
|
| 46 | + @Test |
| 47 | + public void trampoliningWithDeferredResult() { |
| 48 | + assertThat(LambdaIterable.wrap(singletonList(0)) |
| 49 | + .trampolineM(x -> wrap(x < STACK_EXPLODING_NUMBER |
| 50 | + ? singleton(recurse(x + 1)) |
| 51 | + : singleton(terminate(x)))) |
| 52 | + .unwrap(), |
| 53 | + iterates(STACK_EXPLODING_NUMBER)); |
| 54 | + } |
| 55 | + |
| 56 | + @Test |
| 57 | + public void trampoliningOncePerElement() { |
| 58 | + assertThat(LambdaIterable.wrap(asList(1, 2, 3)) |
| 59 | + .trampolineM(x -> wrap(x < STACK_EXPLODING_NUMBER |
| 60 | + ? singleton(recurse(x + 1)) |
| 61 | + : singleton(terminate(x)))) |
| 62 | + .unwrap(), |
| 63 | + iterates(STACK_EXPLODING_NUMBER, STACK_EXPLODING_NUMBER, STACK_EXPLODING_NUMBER)); |
| 64 | + } |
| 65 | + |
| 66 | + @Test |
| 67 | + public void trampoliningWithIncrementalResults() { |
| 68 | + assertThat(LambdaIterable.wrap(singletonList(0)) |
| 69 | + .trampolineM(x -> wrap(x < 10 |
| 70 | + ? asList(terminate(x), recurse(x + 1)) |
| 71 | + : singleton(terminate(x)))) |
| 72 | + .unwrap(), |
| 73 | + iterates(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); |
| 74 | + } |
| 75 | + |
42 | 76 | @Test |
43 | 77 | public void zipAppliesCartesianProductOfFunctionsAndValues() { |
44 | 78 | LambdaIterable<Integer> xs = wrap(asList(1, 2, 3)); |
|
0 commit comments