Skip to content

Commit f8af461

Browse files
committed
#77: Improved show for list, tree, set, treemap, stream, array, V arity 2 to 8, HList
1 parent 2ea0d2d commit f8af461

3 files changed

Lines changed: 112 additions & 39 deletions

File tree

core/src/main/java/fj/Show.java

Lines changed: 90 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import fj.data.NonEmptyList;
99
import fj.data.Option;
1010
import fj.data.Stream;
11+
import fj.data.Set;
12+
import fj.data.TreeMap;
1113
import fj.data.Tree;
1214
import fj.data.Validation;
1315
import fj.data.hlist.HList;
@@ -282,7 +284,7 @@ public static <A, B> Show<Validation<A, B>> validationShow(final Show<A> sa, fin
282284
* @return A show instance for the {@link Stream} type.
283285
*/
284286
public static <A> Show<List<A>> listShow(final Show<A> sa) {
285-
return show(as -> streamShow(sa).show(as.toStream()));
287+
return show(as -> streamShow(sa, "List(", ",", ")").show(as.toStream()));
286288
}
287289

288290
/**
@@ -303,21 +305,91 @@ public static <A> Show<NonEmptyList<A>> nonEmptyListShow(final Show<A> sa) {
303305
*/
304306
public static <A> Show<Tree<A>> treeShow(final Show<A> sa) {
305307
return show(a -> {
306-
final Stream<Character> b = sa.f.f(a.root())
307-
.append(p1Show(streamShow(Show.<A>treeShow(sa))).f.f(a.subForest()))
308-
.snoc(')');
309-
return cons('(', p(b));
308+
Stream<Character> result = sa.f.f(a.root());
309+
if (!a.subForest()._1().isEmpty()) {
310+
result = result.append(fromString(",")).append(streamShow(treeShow(sa), "", ",", "").f.f(a.subForest()._1()));
311+
}
312+
return fromString("Tree(").append(p(result)).append(fromString(")"));
310313
});
311314
}
312315

316+
/**
317+
* A show instance for the {@link Set} type.
318+
*
319+
* @param sa Show for the elements of the set.
320+
* @return A show instance for the {@link Set} type.
321+
*/
322+
public static <A> Show<Set<A>> setShow(final Show<A> sa) {
323+
return show(s -> streamShow(sa, "Set(", ",", ")").show(s.toStream()));
324+
}
325+
326+
/**
327+
* A show instance for the {@link TreeMap} type.
328+
*
329+
* @param sk Show for the keys of the TreeMap.
330+
* @param sv Show for the values of the TreeMap.
331+
* @return A show instance for the {@link TreeMap} type.
332+
*/
333+
public static <K, V> Show<TreeMap<K, V>> treeMapShow(final Show<K> sk, final Show<V> sv) {
334+
return show(tm -> {
335+
Stream<P2<K, V>> stream = Stream.iteratorStream(tm.iterator());
336+
return streamShow(Show.p2MapShow(sk, sv), "TreeMap(", ",", ")").show(stream);
337+
});
338+
}
339+
340+
/**
341+
* A show instance for the {@link P2 tuple-2} type in the style of a mapping from A to B.
342+
*
343+
* @param sa Show for the first element of the tuple.
344+
* @param sb Show for the second element of the tuple.
345+
* @return A show instance for the {@link P2 tuple-2} type.
346+
*/
347+
public static <A, B> Show<P2<A, B>> p2MapShow(final Show<A> sa, final Show<B> sb) {
348+
return p2Show(sa, sb, "(", ":", ")");
349+
}
350+
351+
/**
352+
* A show instance for the {@link P2 tuple-2} type.
353+
*
354+
* @param sa Show for the first element of the tuple.
355+
* @param sb Show for the second element of the tuple.
356+
* @param start Prefix string for the show.
357+
* @param sep Separator string between elements of the tuple.
358+
* @param end Suffix string for the show.
359+
* @return A show instance for the {@link P2 tuple-2} type.
360+
*/
361+
public static <A, B> Show<P2<A, B>> p2Show(final Show<A> sa, final Show<B> sb, String start, String sep, String end) {
362+
return show(p -> fromString(start).append(p(sa.show(p._1()))).append(fromString(sep)).append(sb.show(p._2())).append(fromString(end)));
363+
}
364+
313365
/**
314366
* A show instance for the {@link Stream} type.
315367
*
316368
* @param sa Show for the elements of the stream.
317369
* @return A show instance for the {@link Stream} type.
318370
*/
319371
public static <A> Show<Stream<A>> streamShow(final Show<A> sa) {
320-
return show(as -> join(as.map(sa.show_()).intersperse(fromString(",")).cons(fromString("<")).snoc(p(fromString(">")))));
372+
return streamShow(sa, "Stream(", ",", ")");
373+
}
374+
375+
/**
376+
* A show instance for the {@link Stream} type.
377+
*
378+
* @param sa Show for the first element of the tuple.
379+
* @param start Prefix string for the show.
380+
* @param sep Separator string between elements of the stream.
381+
* @param end Suffix string for the show.
382+
* @return A show instance for the {@link Stream} type.
383+
*/
384+
public static <A> Show<Stream<A>> streamShow(final Show<A> sa, String start, String sep, String end) {
385+
return show(streamShow_(sa, start, sep, end));
386+
}
387+
388+
/**
389+
* Returns the transformation equivalent for the stream show.
390+
*/
391+
public static <A> F<Stream<A>, Stream<Character>> streamShow_(final Show<A> sa, String start, String sep, String end) {
392+
return as -> join(as.map(sa.show_()).intersperse(fromString(sep)).cons(fromString(start)).snoc(p(fromString(end))));
321393
}
322394

323395
/**
@@ -334,12 +406,12 @@ public static <A> Show<Array<A>> arrayShow(final Show<A> sa) {
334406
b = b.append(sa.f.f(as.get(i)));
335407

336408
if (i != as.length() - 1)
337-
b = b.snoc(',');
409+
b = b.append(fromString(","));
338410
}
339411

340-
b = b.snoc('}');
412+
b = b.append(fromString("Array("));
341413

342-
return cons('{', p(b));
414+
return fromString(")").append(p(b));
343415
});
344416
}
345417

@@ -370,7 +442,7 @@ public static <A> Show<P1<A>> p1Show(final Show<A> sa) {
370442
* @return A show instance for the {@link P2 tuple-2} type.
371443
*/
372444
public static <A, B> Show<P2<A, B>> p2Show(final Show<A> sa, final Show<B> sb) {
373-
return show(p -> cons('(', p(sa.show(p._1()))).snoc(',').append(sb.show(p._2())).snoc(')'));
445+
return p2Show(sa, sb, "(", ",", ")");
374446
}
375447

376448
/**
@@ -487,7 +559,7 @@ public static <A, B, C, D, E> Show<P5<A, B, C, D, E>> p5Show(final Show<A> sa, f
487559
* @return A show instance for a vector-2.
488560
*/
489561
public static <A> Show<V2<A>> v2Show(final Show<A> ea) {
490-
return streamShow(ea).comap(V2.<A>toStream_());
562+
return streamShow(ea, "V2(", ",", ")").comap(V2.<A>toStream_());
491563
}
492564

493565
/**
@@ -497,7 +569,7 @@ public static <A> Show<V2<A>> v2Show(final Show<A> ea) {
497569
* @return A show instance for a vector-3.
498570
*/
499571
public static <A> Show<V3<A>> v3Show(final Show<A> ea) {
500-
return streamShow(ea).comap(V3.<A>toStream_());
572+
return streamShow(ea, "V3(", ",", ")").comap(V3.<A>toStream_());
501573
}
502574

503575
/**
@@ -507,7 +579,7 @@ public static <A> Show<V3<A>> v3Show(final Show<A> ea) {
507579
* @return A show instance for a vector-4.
508580
*/
509581
public static <A> Show<V4<A>> v4Show(final Show<A> ea) {
510-
return streamShow(ea).comap(V4.<A>toStream_());
582+
return streamShow(ea, "V4(", ",", ")").comap(V4.<A>toStream_());
511583
}
512584

513585
/**
@@ -517,7 +589,7 @@ public static <A> Show<V4<A>> v4Show(final Show<A> ea) {
517589
* @return A show instance for a vector-5.
518590
*/
519591
public static <A> Show<V5<A>> v5Show(final Show<A> ea) {
520-
return streamShow(ea).comap(V5.<A>toStream_());
592+
return streamShow(ea, "V5(", ",", ")").comap(V5.<A>toStream_());
521593
}
522594

523595
/**
@@ -527,7 +599,7 @@ public static <A> Show<V5<A>> v5Show(final Show<A> ea) {
527599
* @return A show instance for a vector-6.
528600
*/
529601
public static <A> Show<V6<A>> v6Show(final Show<A> ea) {
530-
return streamShow(ea).comap(V6.<A>toStream_());
602+
return streamShow(ea, "V6(", ",", ")").comap(V6.<A>toStream_());
531603
}
532604

533605
/**
@@ -537,7 +609,7 @@ public static <A> Show<V6<A>> v6Show(final Show<A> ea) {
537609
* @return A show instance for a vector-7.
538610
*/
539611
public static <A> Show<V7<A>> v7Show(final Show<A> ea) {
540-
return streamShow(ea).comap(V7.<A>toStream_());
612+
return streamShow(ea, "V7(", ",", ")").comap(V7.<A>toStream_());
541613
}
542614

543615
/**
@@ -547,7 +619,7 @@ public static <A> Show<V7<A>> v7Show(final Show<A> ea) {
547619
* @return A show instance for a vector-8.
548620
*/
549621
public static <A> Show<V8<A>> v8Show(final Show<A> ea) {
550-
return streamShow(ea).comap(V8.<A>toStream_());
622+
return streamShow(ea, "V8(", ",", ")").comap(V8.<A>toStream_());
551623
}
552624

553625
/**
@@ -583,6 +655,6 @@ public static <A> Show<Stream<A>> unlineShow(final Show<A> sa) {
583655
* @return a show instance for heterogeneous Streams.
584656
*/
585657
public static <E, L extends HList<L>> Show<HList.HCons<E, L>> HListShow(final Show<E> e, final Show<L> l) {
586-
return show(c -> e.show(c.head()).cons('[').append(l.show(c.tail())).snoc(']'));
658+
return show(c -> fromString("HList(").append(e.show(c.head())).append(l.show(c.tail())).append(fromString(")")));
587659
}
588660
}

core/src/main/java/fj/data/Stream.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1587,21 +1587,21 @@ public static <A> Stream<A> iterateWhile(final F<A, A> f, final F<A, Boolean> p,
15871587
* @return A stream from the given iterable.
15881588
*/
15891589
public static <A> Stream<A> iterableStream(final Iterable<A> i) {
1590-
final class Util {
1591-
public <A> Stream<A> iteratorStream(final Iterator<A> i) {
1592-
if (i.hasNext()) {
1593-
final A a = i.next();
1594-
return cons(a, new P1<Stream<A>>() {
1595-
public Stream<A> _1() {
1596-
return iteratorStream(i);
1597-
}
1598-
});
1599-
} else
1600-
return nil();
1601-
}
1602-
}
1590+
return iteratorStream(i.iterator());
1591+
}
16031592

1604-
return new Util().iteratorStream(i.iterator());
1593+
/**
1594+
* Takes the given iterator to a stream.
1595+
*
1596+
* @param i The iterator to take to a stream.
1597+
* @return A stream from the given iterator.
1598+
*/
1599+
public static <A> Stream<A> iteratorStream(final Iterator<A> i) {
1600+
if (i.hasNext()) {
1601+
final A a = i.next();
1602+
return cons(a, P.lazy(u -> iteratorStream(i)));
1603+
} else
1604+
return nil();
16051605
}
16061606

16071607
/**

core/src/test/java/fj/data/TestRngState.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@
2222
*/
2323
public class TestRngState {
2424

25-
static String expected1 = "<4,4,2,2,2,5,3,3,1,5>";
25+
static List<Integer> expected1 = List.list(4,4,2,2,2,5,3,3,1,5);
2626
static int size = 10;
27+
static final Equal<List<Integer>> listIntEqual = Equal.listEqual(Equal.intEqual);
2728

2829
static Rng defaultRng() {
2930
return new LcgRng(1);
@@ -48,10 +49,10 @@ static P2<Rng, Integer> num(Rng r, int x) {
4849
@Test
4950
public void testUnfold() {
5051
Stream<Integer> s = unfold(r -> some(num(r).swap()), defaultRng());
51-
Assert.assertTrue(s.take(size).toList().toString().equals(expected1));
52+
Assert.assertTrue(listIntEqual.eq(s.take(size).toList(), expected1));
5253
}
5354

54-
@Test
55+
@Test
5556
public void testTransitions() {
5657
P2<List<State<Rng, Integer>>, State<Rng, Integer>> p = List.replicate(size, nextState()).foldLeft(
5758
(P2<List<State<Rng, Integer>>, State<Rng, Integer>> p2, F<State<Rng, Integer>, State<Rng, Integer>> f) -> {
@@ -61,21 +62,21 @@ public void testTransitions() {
6162
, P.p(List.nil(), defaultState())
6263
);
6364
List<Integer> ints = p._1().map(s -> s.eval(defaultRng()));
64-
Assert.assertTrue(ints.toString().equals(expected1));
65+
Assert.assertTrue(listIntEqual.eq(ints, expected1));
6566
}
6667

6768
@Test
6869
public void testSequence() {
6970
List<Integer> list = State.sequence(List.replicate(size, defaultState())).eval(defaultRng());
70-
Assert.assertTrue(list.toString().equals(expected1));
71+
Assert.assertTrue(listIntEqual.eq(list, expected1));
7172
}
7273

7374
@Test
7475
public void testTraverse() {
7576
List<Integer> list = State.traverse(List.range(1, 10), a -> (State.unit((Rng s) -> num(s, a)))).eval(defaultRng());
7677
// System.out.println(list.toString());
77-
String expected = "<1,2,3,5,6,7,7,9,10>";
78-
Assert.assertTrue(list.toString().equals(expected));
78+
List<Integer> expected = List.list(1,2,3,5,6,7,7,9,10);
79+
Assert.assertTrue(listIntEqual.eq(list, expected));
7980
}
8081

8182
public static Arbitrary<State<LcgRng, Integer>> arbState() {

0 commit comments

Comments
 (0)