001 package fj.pre; 002 003 import static fj.Function.compose; 004 import fj.Class; 005 import fj.F; 006 import fj.Function; 007 import fj.P1; 008 import fj.P2; 009 import fj.P3; 010 import fj.P4; 011 import fj.P5; 012 import fj.P6; 013 import fj.P7; 014 import fj.P8; 015 import fj.Unit; 016 import static fj.P.p; 017 import static fj.Unit.unit; 018 import fj.data.hlist.HList; 019 import fj.data.*; 020 import static fj.data.Stream.*; 021 import fj.data.vector.V2; 022 import fj.data.vector.V3; 023 import fj.data.vector.V4; 024 import fj.data.vector.V5; 025 import fj.data.vector.V6; 026 import fj.data.vector.V7; 027 import fj.data.vector.V8; 028 029 import java.math.BigInteger; 030 import java.math.BigDecimal; 031 import java.util.Arrays; 032 033 /** 034 * Renders an object for display. 035 * 036 * @version %build.number%<br> 037 * <ul> 038 * <li>$LastChangedRevision: 152 $</li> 039 * <li>$LastChangedDate: 2009-05-30 18:27:20 +1000 (Sat, 30 May 2009) $</li> 040 * </ul> 041 */ 042 public final class Show<A> { 043 private final F<A, Stream<Character>> f; 044 045 private Show(final F<A, Stream<Character>> f) { 046 this.f = f; 047 } 048 049 /** 050 * Maps the given function across this show as a contra-variant functor. 051 * 052 * @param f The function to map. 053 * @return A new show. 054 */ 055 public <B> Show<B> comap(final F<B, A> f) { 056 return show(compose(this.f, f)); 057 } 058 059 /** 060 * Returns the display rendering of the given argument. 061 * 062 * @param a The argument to display. 063 * @return The display rendering of the given argument. 064 */ 065 public Stream<Character> show(final A a) { 066 return f.f(a); 067 } 068 069 /** 070 * Returns the display rendering of the given argument. 071 * 072 * @param a The argument to display. 073 * @return The display rendering of the given argument. 074 */ 075 public List<Character> showl(final A a) { 076 return show(a).toList(); 077 } 078 079 /** 080 * Returns the display rendering of the given argument as a <code>String</code>. 081 * 082 * @param a The argument to display. 083 * @return The display rendering of the given argument as a <code>String</code>. 084 */ 085 public String showS(final A a) { 086 return Stream.asString(show(a)); 087 } 088 089 /** 090 * Returns the transformation equivalent to this show. 091 * 092 * @return the transformation equivalent to this show. 093 */ 094 public F<A, String> showS_() { 095 return new F<A, String>() { 096 public String f(final A a) { 097 return showS(a); 098 } 099 }; 100 } 101 102 /** 103 * Returns the transformation equivalent to this show. 104 * 105 * @return the transformation equivalent to this show. 106 */ 107 public F<A, Stream<Character>> show_() { 108 return f; 109 } 110 111 /** 112 * Prints the given argument to the standard output stream with a new line. 113 * 114 * @param a The argument to print. 115 * @return The unit value. 116 */ 117 public Unit println(final A a) { 118 print(a); 119 System.out.println(); 120 return unit(); 121 } 122 123 /** 124 * Prints the given argument to the standard output stream. 125 * 126 * @param a The argument to print. 127 * @return The unit value. 128 */ 129 public Unit print(final A a) { 130 final char[] buffer = new char[8192]; 131 int c = 0; 132 for (Stream<Character> cs = show(a); cs.isNotEmpty(); cs = cs.tail()._1()) { 133 buffer[c] = cs.head(); 134 c++; 135 if (c == 8192) { 136 System.out.print(buffer); 137 c = 0; 138 } 139 } 140 System.out.print(Arrays.copyOfRange(buffer, 0, c)); 141 return unit(); 142 } 143 144 /** 145 * Prints the given argument to the standard error stream with a new line. 146 * 147 * @param a The argument to print. 148 */ 149 public void printlnE(final A a) { 150 System.err.println(showS(a)); 151 } 152 153 /** 154 * Returns a show instance using the given function. 155 * 156 * @param f The function to use for the returned show instance. 157 * @return A show instance. 158 */ 159 public static <A> Show<A> show(final F<A, Stream<Character>> f) { 160 return new Show<A>(f); 161 } 162 163 /** 164 * Returns a show instance using the given function. 165 * 166 * @param f The function to use for the returned show instance. 167 * @return A show instance. 168 */ 169 public static <A> Show<A> showS(final F<A, String> f) { 170 return new Show<A>(new F<A, Stream<Character>>() { 171 public Stream<Character> f(final A a) { 172 return fromString(f.f(a)); 173 } 174 }); 175 } 176 177 /** 178 * Returns a show instance that uses {@link Object#toString()} to perform the display rendering. 179 * 180 * @return A show instance that uses {@link Object#toString()} to perform the display rendering. 181 */ 182 public static <A> Show<A> anyShow() { 183 return new Show<A>(new F<A, Stream<Character>>() { 184 public Stream<Character> f(final A a) { 185 return Stream.fromString(a.toString()); 186 } 187 }); 188 } 189 190 /** 191 * A show instance for the <code>boolean</code> type. 192 */ 193 public static final Show<Boolean> booleanShow = anyShow(); 194 195 /** 196 * A show instance for the <code>byte</code> type. 197 */ 198 public static final Show<Byte> byteShow = anyShow(); 199 200 /** 201 * A show instance for the <code>char</code> type. 202 */ 203 public static final Show<Character> charShow = anyShow(); 204 205 /** 206 * A show instance for the <code>double</code> type. 207 */ 208 public static final Show<Double> doubleShow = anyShow(); 209 210 /** 211 * A show instance for the <code>float</code> type. 212 */ 213 public static final Show<Float> floatShow = anyShow(); 214 215 /** 216 * A show instance for the <code>int</code> type. 217 */ 218 public static final Show<Integer> intShow = anyShow(); 219 220 /** 221 * A show instance for the <code>BigInteger</code> type. 222 */ 223 public static final Show<BigInteger> bigintShow = anyShow(); 224 225 /** 226 * A show instance for the <code>BigDecimal</code> type. 227 */ 228 public static final Show<BigDecimal> bigdecimalShow = anyShow(); 229 230 /** 231 * A show instance for the <code>long</code> type. 232 */ 233 public static final Show<Long> longShow = anyShow(); 234 235 /** 236 * A show instance for the <code>short</code> type. 237 */ 238 public static final Show<Short> shortShow = anyShow(); 239 240 /** 241 * A show instance for the {@link String} type. 242 */ 243 public static final Show<String> stringShow = anyShow(); 244 245 /** 246 * A show instance for the {@link StringBuffer} type. 247 */ 248 public static final Show<StringBuffer> stringBufferShow = anyShow(); 249 250 /** 251 * A show instance for the {@link StringBuilder} type. 252 */ 253 public static final Show<StringBuilder> stringBuilderShow = anyShow(); 254 255 /** 256 * A show instance for the {@link Option} type. 257 * 258 * @param sa Show for the element of the option. 259 * @return A show instance for the {@link Option} type. 260 */ 261 public static <A> Show<Option<A>> optionShow(final Show<A> sa) { 262 return new Show<Option<A>>(new F<Option<A>, Stream<Character>>() { 263 public Stream<Character> f(final Option<A> o) { 264 return o.isNone() ? 265 fromString("None") : 266 fromString("Some(").append(sa.f.f(o.some())).append(single(')')); 267 } 268 }); 269 } 270 271 /** 272 * A show instance for the {@link Either} type. 273 * 274 * @param sa Show for the left side of the {@link Either}. 275 * @param sb Show for the right side of the {@link Either}. 276 * @return A show instance for the {@link Either} type. 277 */ 278 public static <A, B> Show<Either<A, B>> eitherShow(final Show<A> sa, final Show<B> sb) { 279 return new Show<Either<A, B>>(new F<Either<A, B>, Stream<Character>>() { 280 public Stream<Character> f(final Either<A, B> e) { 281 return e.isLeft() ? 282 fromString("Left(").append(sa.f.f(e.left().value())).append(single(')')) : 283 fromString("Right(").append(sb.f.f(e.right().value())).append(single(')')); 284 } 285 }); 286 } 287 288 /** 289 * A show instance for the {@link Validation} type. 290 * 291 * @param sa Show for the fail side of the {@link Validation}. 292 * @param sb Show for the success side of the {@link Validation}. 293 * @return A show instance for the {@link Validation} type. 294 */ 295 public static <A, B> Show<Validation<A, B>> validationShow(final Show<A> sa, final Show<B> sb) { 296 return new Show<Validation<A, B>>(new F<Validation<A, B>, Stream<Character>>() { 297 public Stream<Character> f(final Validation<A, B> v) { 298 return v.isFail() ? 299 fromString("Fail(").append(sa.f.f(v.fail())).append(single(')')) : 300 fromString("Success(").append(sb.f.f(v.success())).append(single(')')); 301 } 302 }); 303 } 304 305 /** 306 * A show instance for the {@link Stream} type. 307 * 308 * @param sa Show for the elements of the Stream. 309 * @return A show instance for the {@link Stream} type. 310 */ 311 public static <A> Show<List<A>> listShow(final Show<A> sa) { 312 return new Show<List<A>>(new F<List<A>, Stream<Character>>() { 313 public Stream<Character> f(final List<A> as) { 314 return streamShow(sa).show(as.toStream()); 315 } 316 }); 317 } 318 319 /** 320 * A show instance for the {@link NonEmptyList} type. 321 * 322 * @param sa Show for the elements of the non-empty Stream. 323 * @return A show instance for the {@link NonEmptyList} type. 324 */ 325 public static <A> Show<NonEmptyList<A>> nonEmptyListShow(final Show<A> sa) { 326 return listShow(sa).comap(NonEmptyList.<A>toList_()); 327 } 328 329 /** 330 * A show instance for the {@link Tree} type. 331 * 332 * @param sa Show for the elements of the tree. 333 * @return A show instance for the {@link Tree} type. 334 */ 335 public static <A> Show<Tree<A>> treeShow(final Show<A> sa) { 336 return new Show<Tree<A>>(new F<Tree<A>, Stream<Character>>() { 337 public Stream<Character> f(final Tree<A> a) { 338 Stream<Character> b = sa.f.f(a.root()) 339 .append(p1Show(streamShow(treeShow(sa))).f.f(a.subForest())) 340 .snoc(')'); 341 return cons('(', p(b)); 342 } 343 }); 344 } 345 346 /** 347 * A show instance for the {@link Stream} type. 348 * 349 * @param sa Show for the elements of the stream. 350 * @return A show instance for the {@link Stream} type. 351 */ 352 public static <A> Show<Stream<A>> streamShow(final Show<A> sa) { 353 return new Show<Stream<A>>(new F<Stream<A>, Stream<Character>>() { 354 public Stream<Character> f(final Stream<A> as) { 355 return join(as.map(sa.show_()).intersperse(fromString(",")).cons(fromString("<")).snoc(p(fromString(">")))); 356 } 357 }); 358 } 359 360 /** 361 * A show instance for the {@link Array} type. 362 * 363 * @param sa Show for the elements of the array. 364 * @return A show instance for the {@link Array} type. 365 */ 366 public static <A> Show<Array<A>> arrayShow(final Show<A> sa) { 367 return new Show<Array<A>>(new F<Array<A>, Stream<Character>>() { 368 public Stream<Character> f(final Array<A> as) { 369 Stream<Character> b = nil(); 370 371 for (int i = 0; i < as.length(); i++) { 372 b = b.append(sa.f.f(as.get(i))); 373 374 if (i != as.length() - 1) 375 b = b.snoc(','); 376 } 377 378 b = b.snoc('}'); 379 380 return cons('{', p(b)); 381 } 382 }); 383 } 384 385 /** 386 * A show instance for the {@link Class} type. 387 * 388 * @return A show instance for the {@link Class} type. 389 */ 390 public static <A> Show<Class<A>> classShow() { 391 return new Show<Class<A>>(new F<fj.Class<A>, Stream<Character>>() { 392 public Stream<Character> f(final Class<A> c) { 393 return anyShow().show(c.clas()); 394 } 395 }); 396 } 397 398 /** 399 * A show instance for the {@link P1 tuple-1} type. 400 * 401 * @param sa Show for the first element of the tuple. 402 * @return A show instance for the {@link P1 tuple-1} type. 403 */ 404 public static <A> Show<P1<A>> p1Show(final Show<A> sa) { 405 return new Show<P1<A>>(new F<P1<A>, Stream<Character>>() { 406 public Stream<Character> f(final P1<A> p) { 407 return cons('(', p(sa.show(p._1()))).snoc(')'); 408 } 409 }); 410 } 411 412 /** 413 * A show instance for the {@link P2 tuple-2} type. 414 * 415 * @param sa Show for the first element of the tuple. 416 * @param sb Show for the second element of the tuple. 417 * @return A show instance for the {@link P2 tuple-2} type. 418 */ 419 public static <A, B> Show<P2<A, B>> p2Show(final Show<A> sa, final Show<B> sb) { 420 return new Show<P2<A, B>>(new F<P2<A, B>, Stream<Character>>() { 421 public Stream<Character> f(final P2<A, B> p) { 422 return cons('(', p(sa.show(p._1()))).snoc(',').append(sb.show(p._2())).snoc(')'); 423 } 424 }); 425 } 426 427 /** 428 * A show instance for the {@link P3 tuple-3} type. 429 * 430 * @param sa Show for the first element of the tuple. 431 * @param sb Show for the second element of the tuple. 432 * @param sc Show for the third element of the tuple. 433 * @return A show instance for the {@link P3 tuple-3} type. 434 */ 435 public static <A, B, C> Show<P3<A, B, C>> p3Show(final Show<A> sa, final Show<B> sb, final Show<C> sc) { 436 return new Show<P3<A, B, C>>(new F<P3<A, B, C>, Stream<Character>>() { 437 public Stream<Character> f(final P3<A, B, C> p) { 438 return cons('(', p(sa.show(p._1()))).snoc(',').append(sb.show(p._2())).snoc(',') 439 .append(sc.show(p._3())).snoc(')'); 440 } 441 }); 442 } 443 444 /** 445 * A show instance for the {@link P4 tuple-4} type. 446 * 447 * @param sa Show for the first element of the tuple. 448 * @param sb Show for the second element of the tuple. 449 * @param sc Show for the third element of the tuple. 450 * @param sd Show for the fourth element of the tuple. 451 * @return A show instance for the {@link P4 tuple-4} type. 452 */ 453 public static <A, B, C, D> Show<P4<A, B, C, D>> p4Show(final Show<A> sa, final Show<B> sb, 454 final Show<C> sc, final Show<D> sd) { 455 return new Show<P4<A, B, C, D>>(new F<P4<A, B, C, D>, Stream<Character>>() { 456 public Stream<Character> f(final P4<A, B, C, D> p) { 457 return cons('(', p(sa.show(p._1()))).snoc(',').append(sb.show(p._2())).snoc(',') 458 .append(sc.show(p._3())).snoc(',').append(sd.show(p._4())).snoc(')'); 459 } 460 }); 461 } 462 463 /** 464 * A show instance for the {@link P5 tuple-5} type. 465 * 466 * @param sa Show for the first element of the tuple. 467 * @param sb Show for the second element of the tuple. 468 * @param sc Show for the third element of the tuple. 469 * @param sd Show for the fourth element of the tuple. 470 * @param se Show for the fifth element of the tuple. 471 * @return A show instance for the {@link P5 tuple-5} type. 472 */ 473 public static <A, B, C, D, E> Show<P5<A, B, C, D, E>> p5Show(final Show<A> sa, final Show<B> sb, 474 final Show<C> sc, final Show<D> sd, final Show<E> se) { 475 return new Show<P5<A, B, C, D, E>>(new F<P5<A, B, C, D, E>, Stream<Character>>() { 476 public Stream<Character> f(final P5<A, B, C, D, E> p) { 477 return cons('(', p(sa.show(p._1()))).snoc(',').append(sb.show(p._2())).snoc(',') 478 .append(sc.show(p._3())).snoc(',').append(sd.show(p._4())).snoc(',').append(se.show(p._5())).snoc(')'); 479 } 480 }); 481 } 482 483 /** 484 * A show instance for the {@link P6 tuple-6} type. 485 * 486 * @param sa Show for the first element of the tuple. 487 * @param sb Show for the second element of the tuple. 488 * @param sc Show for the third element of the tuple. 489 * @param sd Show for the fourth element of the tuple. 490 * @param se Show for the fifth element of the tuple. 491 * @param sf Show for the sixth element of the tuple. 492 * @return A show instance for the {@link P6 tuple-6} type. 493 */ 494 public static <A, B, C, D, E, F$> Show<P6<A, B, C, D, E, F$>> p6Show(final Show<A> sa, final Show<B> sb, 495 final Show<C> sc, final Show<D> sd, 496 final Show<E> se, final Show<F$> sf) { 497 return new Show<P6<A, B, C, D, E, F$>>(new F<P6<A, B, C, D, E, F$>, Stream<Character>>() { 498 public Stream<Character> f(final P6<A, B, C, D, E, F$> p) { 499 return cons('(', p(sa.show(p._1()))).snoc(',').append(sb.show(p._2())).snoc(',') 500 .append(sc.show(p._3())).snoc(',').append(sd.show(p._4())).snoc(',') 501 .append(se.show(p._5())).snoc(',').append(sf.show(p._6())).snoc(')'); 502 } 503 }); 504 } 505 506 /** 507 * A show instance for the {@link P7 tuple-7} type. 508 * 509 * @param sa Show for the first element of the tuple. 510 * @param sb Show for the second element of the tuple. 511 * @param sc Show for the third element of the tuple. 512 * @param sd Show for the fourth element of the tuple. 513 * @param se Show for the fifth element of the tuple. 514 * @param sf Show for the sixth element of the tuple. 515 * @param sg Show for the seventh element of the tuple. 516 * @return A show instance for the {@link P7 tuple-7} type. 517 */ 518 public static <A, B, C, D, E, F$, G> Show<P7<A, B, C, D, E, F$, G>> p7Show(final Show<A> sa, final Show<B> sb, 519 final Show<C> sc, final Show<D> sd, 520 final Show<E> se, final Show<F$> sf, 521 final Show<G> sg) { 522 return new Show<P7<A, B, C, D, E, F$, G>>(new F<P7<A, B, C, D, E, F$, G>, Stream<Character>>() { 523 public Stream<Character> f(final P7<A, B, C, D, E, F$, G> p) { 524 return cons('(', p(sa.show(p._1()))).snoc(',').append(sb.show(p._2())).snoc(',') 525 .append(sc.show(p._3())).snoc(',').append(sd.show(p._4())).snoc(',') 526 .append(se.show(p._5())).snoc(',').append(sf.show(p._6())).snoc(',').append(sg.show(p._7())).snoc(')'); 527 } 528 }); 529 } 530 531 /** 532 * A show instance for the {@link P8 tuple-8} type. 533 * 534 * @param sa Show for the first element of the tuple. 535 * @param sb Show for the second element of the tuple. 536 * @param sc Show for the third element of the tuple. 537 * @param sd Show for the fourth element of the tuple. 538 * @param se Show for the fifth element of the tuple. 539 * @param sf Show for the sixth element of the tuple. 540 * @param sg Show for the seventh element of the tuple. 541 * @param sh Show for the eighth element of the tuple. 542 * @return A show instance for the {@link P8 tuple-8} type. 543 */ 544 public static <A, B, C, D, E, F$, G, H> Show<P8<A, B, C, D, E, F$, G, H>> p8Show(final Show<A> sa, final Show<B> sb, 545 final Show<C> sc, final Show<D> sd, 546 final Show<E> se, final Show<F$> sf, 547 final Show<G> sg, final Show<H> sh) { 548 return new Show<P8<A, B, C, D, E, F$, G, H>>(new F<P8<A, B, C, D, E, F$, G, H>, Stream<Character>>() { 549 public Stream<Character> f(final P8<A, B, C, D, E, F$, G, H> p) { 550 return cons('(', p(sa.show(p._1()))).snoc(',').append(sb.show(p._2())).snoc(',') 551 .append(sc.show(p._3())).snoc(',').append(sd.show(p._4())).snoc(',') 552 .append(se.show(p._5())).snoc(',').append(sf.show(p._6())).snoc(',') 553 .append(sg.show(p._7())).snoc(',').append(sh.show(p._8())).snoc(')'); 554 } 555 }); 556 } 557 558 /** 559 * A show instance for a vector-2. 560 * 561 * @param ea A show for the elements of the vector. 562 * @return A show instance for a vector-2. 563 */ 564 public static <A> Show<V2<A>> v2Show(final Show<A> ea) { 565 return streamShow(ea).comap(V2.<A>toStream_()); 566 } 567 568 /** 569 * A show instance for a vector-3. 570 * 571 * @param ea A show for the elements of the vector. 572 * @return A show instance for a vector-3. 573 */ 574 public static <A> Show<V3<A>> v3Show(final Show<A> ea) { 575 return streamShow(ea).comap(V3.<A>toStream_()); 576 } 577 578 /** 579 * A show instance for a vector-4. 580 * 581 * @param ea A show for the elements of the vector. 582 * @return A show instance for a vector-4. 583 */ 584 public static <A> Show<V4<A>> v4Show(final Show<A> ea) { 585 return streamShow(ea).comap(V4.<A>toStream_()); 586 } 587 588 /** 589 * A show instance for a vector-5. 590 * 591 * @param ea A show for the elements of the vector. 592 * @return A show instance for a vector-5. 593 */ 594 public static <A> Show<V5<A>> v5Show(final Show<A> ea) { 595 return streamShow(ea).comap(V5.<A>toStream_()); 596 } 597 598 /** 599 * A show instance for a vector-6. 600 * 601 * @param ea A show for the elements of the vector. 602 * @return A show instance for a vector-6. 603 */ 604 public static <A> Show<V6<A>> v6Show(final Show<A> ea) { 605 return streamShow(ea).comap(V6.<A>toStream_()); 606 } 607 608 /** 609 * A show instance for a vector-7. 610 * 611 * @param ea A show for the elements of the vector. 612 * @return A show instance for a vector-7. 613 */ 614 public static <A> Show<V7<A>> v7Show(final Show<A> ea) { 615 return streamShow(ea).comap(V7.<A>toStream_()); 616 } 617 618 /** 619 * A show instance for a vector-8. 620 * 621 * @param ea A show for the elements of the vector. 622 * @return A show instance for a vector-8. 623 */ 624 public static <A> Show<V8<A>> v8Show(final Show<A> ea) { 625 return streamShow(ea).comap(V8.<A>toStream_()); 626 } 627 628 /** 629 * A show instance for natural numbers. 630 */ 631 public static final Show<Natural> naturalShow = bigintShow.comap(new F<Natural, BigInteger>() { 632 public BigInteger f(final Natural natural) { 633 return natural.bigIntegerValue(); 634 } 635 }); 636 637 /** 638 * A show instance for streams that splits into lines. 639 * 640 * @param sa A show instance for the elements of a stream. 641 * @return A show instance for streams that splits into lines. 642 */ 643 public static <A> Show<Stream<A>> unlineShow(final Show<A> sa) { 644 return new Show<Stream<A>>(new F<Stream<A>, Stream<Character>>() { 645 public Stream<Character> f(final Stream<A> as) { 646 return join(as.map(sa.show_()).intersperse(fromString("\n"))); 647 } 648 }); 649 } 650 651 /** 652 * A show instance for lazy strings. 653 */ 654 public static final Show<LazyString> lazyStringShow = show(new F<LazyString, Stream<Character>>() { 655 public Stream<Character> f(final LazyString string) { 656 return string.toStream(); 657 } 658 }); 659 660 /** 661 * A show instance for the empty heterogeneous Stream. 662 */ 663 public static final Show<HList.HNil> HListShow = showS(Function.<HList.HNil, String>constant("Nil")); 664 665 /** 666 * A show instance for heterogeneous Streams. 667 * 668 * @param e A show instance for the first element of the Stream. 669 * @param l A show instance for the rest of the Stream. 670 * @return a show instance for heterogeneous Streams. 671 */ 672 public static <E, L extends HList<L>> Show<HList.HCons<E, L>> HListShow(final Show<E> e, final Show<L> l) { 673 return show(new F<HList.HCons<E, L>, Stream<Character>>() { 674 public Stream<Character> f(final HList.HCons<E, L> c) { 675 return e.show(c.head()).cons('[').append(l.show(c.tail())).snoc(']'); 676 } 677 }); 678 } 679 }