package scalaz trait Show[A] { def show(a: A): List[Char] } trait Shows { import Scalaz._ def show[A](f: A => List[Char]): Show[A] = new Show[A] { def show(a: A) = f(a) } def shows[A](f: A => String): Show[A] = show[A](f(_).toList) def showA[A]: Show[A] = shows[A](_.toString) def showBy[A, B: Show](f: A => B): Show[A] = implicitly[Show[B]] ∙ f } object Show { import Scalaz._ import Predef.{implicitly => i} implicit def DigitShow: Show[Digit] = showBy(_.toInt) implicit def OrderingShow: Show[Ordering] = showA implicit def ThrowableShow: Show[Throwable] = showA implicit def StringShow: Show[String] = showA implicit def SymbolShow: Show[Symbol] = showA implicit def UnitShow: Show[Unit] = showA implicit def BooleanShow: Show[Boolean] = showA implicit def ByteShow: Show[Byte] = showA implicit def CharShow: Show[Char] = showA implicit def IntShow: Show[Int] = showA implicit def LongShow: Show[Long] = showA implicit def ShortShow: Show[Short] = showA implicit def FloatShow: Show[Float] = showA implicit def DoubleShow: Show[Double] = showA def NewTypeShow[B: Show, A <: NewType[B]]: Show[A] = showBy(_.value) implicit def IntMultiplicationShow: Show[IntMultiplication] = NewTypeShow[Int, IntMultiplication] implicit def BooleanConjunctionShow: Show[BooleanConjunction] = NewTypeShow[Boolean, BooleanConjunction] implicit def CharMultiplicationShow: Show[CharMultiplication] = NewTypeShow[Char, CharMultiplication] implicit def ByteMultiplicationShow: Show[ByteMultiplication] = NewTypeShow[Byte, ByteMultiplication] implicit def LongMultiplicationShow: Show[LongMultiplication] = NewTypeShow[Long, LongMultiplication] implicit def ShortMultiplicationShow: Show[ShortMultiplication] = NewTypeShow[Short, ShortMultiplication] implicit def BigIntegerShow: Show[java.math.BigInteger] = showA[java.math.BigInteger] implicit def BigIntegerMultiplicationShow: Show[BigIntegerMultiplication] = NewTypeShow[java.math.BigInteger, BigIntegerMultiplication] implicit def BigIntShow: Show[BigInt] = showA implicit def BigIntMultiplicationShow: Show[BigIntMultiplication] = NewTypeShow[BigInt, BigIntMultiplication] implicit def ConstShow[B: Show, A]: Show[Const[B, A]] = NewTypeShow[B, Const[B, A]] implicit def NodeSeqShow: Show[xml.NodeSeq] = showA implicit def NonEmptyListShow[A: Show]: Show[NonEmptyList[A]] = implicitly[Show[Iterable[A]]] ∙ ((_: NonEmptyList[A]).list) implicit def IndSeqShow[A: Show]: Show[IndSeq[A]] = showBy(_.toList) implicit def Function1Show[A, B]: Show[A => B] = show((f: A => B) => "<function>".toList) implicit def ZipStreamShow[A: Show]: Show[ZipStream[A]] = implicitly[Show[Stream[A]]] ∙ ((_: ZipStream[A]).value) implicit def ZipperShow[A: Show]: Show[Zipper[A]] = show((z: Zipper[A]) => z.lefts.reverse.show ++ " " ++ z.focus.show ++ " " ++ z.rights.show) implicit def TreeShow[A: Show]: Show[Tree[A]] = show((t: Tree[A]) => '{' :: t.rootLabel.show ++ " " ++ t.subForest.show ++ "}") implicit def TreeLocShow[A: Show]: Show[TreeLoc[A]] = show((t: TreeLoc[A]) => t.toTree.show ++ "@" ++ t.parents.map(_._1.length).reverse.show) implicit def IterableShow[CC[X] <: Iterable[X], A: Show]: Show[CC[A]] = show((as: CC[A]) => { val i = as.iterator val k = new collection.mutable.ListBuffer[Char] k += '[' while (i.hasNext) { val n = i.next k ++= n.show if (i.hasNext) k += ',' } k += ']' k.toList }) implicit def Tuple1Show[A: Show]: Show[Tuple1[A]] = show(a => { val k = new collection.mutable.ListBuffer[Char] k += '(' k ++= a._1.show k += ')' k.toList }) implicit def Tuple2Show[A: Show, B: Show]: Show[(A, B)] = show { case (a, b) => { val k = new collection.mutable.ListBuffer[Char] k += '(' k ++= a.show k ++= ", ".toList k ++= b.show k += ')' k.toList } } implicit def Tuple3Show[A: Show, B: Show, C: Show]: Show[(A, B, C)] = show { case (a, b, c) => { val k = new collection.mutable.ListBuffer[Char] k += '(' k ++= a.show k ++= ", ".toList k ++= b.show k ++= ", ".toList k ++= c.show k += ')' k.toList } } implicit def Tuple4Show[A: Show, B: Show, C: Show, D: Show]: Show[(A, B, C, D)] = show { case (a, b, c, d) => { val k = new collection.mutable.ListBuffer[Char] k += '(' k ++= a.show k ++= ", ".toList k ++= b.show k ++= ", ".toList k ++= c.show k ++= ", ".toList k ++= d.show k += ')' k.toList } } implicit def Tuple5Show[A: Show, B: Show, C: Show, D: Show, E: Show]: Show[(A, B, C, D, E)] = show { case (a, b, c, d, e) => { val k = new collection.mutable.ListBuffer[Char] k += '(' k ++= a.show k ++= ", ".toList k ++= b.show k ++= ", ".toList k ++= c.show k ++= ", ".toList k ++= d.show k ++= ", ".toList k ++= e.show k += ')' k.toList } } implicit def Tuple6Show[A: Show, B: Show, C: Show, D: Show, E: Show, F: Show]: Show[(A, B, C, D, E, F)] = show { case (a, b, c, d, e, f) => { val k = new collection.mutable.ListBuffer[Char] k += '(' k ++= a.show k ++= ", ".toList k ++= b.show k ++= ", ".toList k ++= c.show k ++= ", ".toList k ++= d.show k ++= ", ".toList k ++= e.show k ++= ", ".toList k ++= f.show k += ')' k.toList } } implicit def Tuple7Show[A: Show, B: Show, C: Show, D: Show, E: Show, F: Show, G: Show]: Show[(A, B, C, D, E, F, G)] = show { case (a, b, c, d, e, f, g) => { val k = new collection.mutable.ListBuffer[Char] k += '(' k ++= a.show k ++= ", ".toList k ++= b.show k ++= ", ".toList k ++= c.show k ++= ", ".toList k ++= d.show k ++= ", ".toList k ++= e.show k ++= ", ".toList k ++= f.show k ++= ", ".toList k ++= g.show k += ')' k.toList } } implicit def Function0Show[A: Show]: Show[() => A] = show(_.apply.show) implicit def OptionShow[A: Show]: Show[Option[A]] = shows(_ map (_.shows) toString) implicit def FirstOptionShow[A: Show]: Show[FirstOption[A]] = OptionShow[A] ∙ ((_: FirstOption[A]).value) implicit def LastOptionShow[A: Show]: Show[LastOption[A]] = OptionShow[A] ∙ ((_: LastOption[A]).value) implicit def LazyOptionShow[A: Show]: Show[LazyOption[A]] = shows(_ map (_.shows) fold("Some(" + _ + ")", "None")) implicit def FirstLazyOptionShow[A: Show]: Show[FirstLazyOption[A]] = LazyOptionShow[A] ∙ ((_: FirstLazyOption[A]).value) implicit def LastLazyOptionShow[A: Show]: Show[LastLazyOption[A]] = LazyOptionShow[A] ∙ ((_: LastLazyOption[A]).value) implicit def EitherShow[A: Show, B: Show]: Show[Either[A, B]] = shows(e => (((_: A).shows) <-: e :-> (_.shows)).toString) implicit def ValidationShow[E: Show, A: Show]: Show[Validation[E, A]] = shows { case Success(a) => "Success(" + a.shows + ")" case Failure(e) => "Failure(" + e.shows + ")" } implicit def MapShow[CC[K, V] <: collection.Map[K, V], A: Show, B: Show]: Show[CC[A, B]] = i[Show[Iterable[(A, B)]]] contravary import java.{lang => jl, util => ju} implicit def JavaIterableEqual[CC[X] <: jl.Iterable[X], A: Show]: Show[CC[A]] = { import scala.collection.JavaConversions._ showBy((i: jl.Iterable[A]) => i: Iterable[A]) } implicit def JavaMapShow[K: Show, V: Show]: Show[ju.Map[K, V]] = show(m => { import collection.JavaConversions val z = new collection.mutable.ListBuffer[Char] z += '{' val i = m.keySet.iterator while (i.hasNext) { val k = i.next val v = m get k z ++= k.show z ++= " -> ".toList z ++= v.show if (i.hasNext) z += ',' } z += '}' z.toList }) }