diff options
author | Felix Mulder <felix.mulder@gmail.com> | 2016-12-14 16:40:31 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-14 16:40:31 +0100 |
commit | ba06bf06721f1a8de7d68d22ad7eba27fff90c43 (patch) | |
tree | a02167f1d4d786c027c600c0070c36055cbc2622 /library/src | |
parent | 19bc03c840f0d6f0678775625562cea5ad7193e7 (diff) | |
parent | 35e8fcb805e7780555cf48160f90c9da71bb1811 (diff) | |
download | dotty-ba06bf06721f1a8de7d68d22ad7eba27fff90c43.tar.gz dotty-ba06bf06721f1a8de7d68d22ad7eba27fff90c43.tar.bz2 dotty-ba06bf06721f1a8de7d68d22ad7eba27fff90c43.zip |
Merge pull request #1761 from dotty-staging/topic/product-show
[REPL] Add show capability to common types
Diffstat (limited to 'library/src')
-rw-r--r-- | library/src/dotty/Show.scala | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/library/src/dotty/Show.scala b/library/src/dotty/Show.scala new file mode 100644 index 000000000..2feeb29ef --- /dev/null +++ b/library/src/dotty/Show.scala @@ -0,0 +1,102 @@ +package dotty + +import scala.annotation.implicitNotFound + +@implicitNotFound("No member of type class Show could be found for ${T}") +trait Show[-T] { + def show(t: T): String +} + +/** Ideally show would only contain `defaultShow` and the pimped generic class, + * but since we can't change the current stdlib, we're stuck with providing + * default instances in this object + */ +object Show { + private[this] val defaultShow: Show[Any] = new Show[Any] { + def show(x: Any) = x.toString + } + + /** This class implements pimping of all types to provide a show method. + * Currently it is quite permissive, if there's no instance of `Show[T]` for + * any `T`, we default to `T#toString`. + */ + implicit class ShowValue[V](val v: V) extends AnyVal { + def show(implicit ev: Show[V] = defaultShow): String = + ev.show(v) + } + + implicit val stringShow: Show[String] = new Show[String] { + // From 2.12 spec, `charEscapeSeq`: + // ‘\‘ (‘b‘ | ‘t‘ | ‘n‘ | ‘f‘ | ‘r‘ | ‘"‘ | ‘'‘ | ‘\‘) + def show(str: String) = + "\"" + { + val sb = new StringBuilder + str.foreach { + case '\b' => sb.append("\\b") + case '\t' => sb.append("\\t") + case '\n' => sb.append("\\n") + case '\f' => sb.append("\\f") + case '\r' => sb.append("\\r") + case '\'' => sb.append("\\'") + case '\"' => sb.append("\\\"") + case c => sb.append(c) + } + sb.toString + } + "\"" + } + + implicit val intShow: Show[Int] = new Show[Int] { + def show(i: Int) = i.toString + } + + implicit val floatShow: Show[Float] = new Show[Float] { + def show(f: Float) = f + "f" + } + + implicit val doubleShow: Show[Double] = new Show[Double] { + def show(d: Double) = d.toString + } + + implicit val charShow: Show[Char] = new Show[Char] { + def show(c: Char) = "'" + (c match { + case '\b' => "\\b" + case '\t' => "\\t" + case '\n' => "\\n" + case '\f' => "\\f" + case '\r' => "\\r" + case '\'' => "\\'" + case '\"' => "\\\"" + case c => c + }) + "'" + } + + implicit def showList[T](implicit st: Show[T]): Show[List[T]] = new Show[List[T]] { + def show(xs: List[T]) = + if (xs.isEmpty) "Nil" + else "List(" + xs.map(_.show).mkString(", ") + ")" + } + + implicit val showNil: Show[Nil.type] = new Show[Nil.type] { + def show(xs: Nil.type) = "Nil" + } + + implicit def showOption[T](implicit st: Show[T]): Show[Option[T]] = new Show[Option[T]] { + def show(ot: Option[T]): String = ot match { + case Some(t) => "Some("+ st.show(t) + ")" + case none => "None" + } + } + + implicit val showNone: Show[None.type] = new Show[None.type] { + def show(n: None.type) = "None" + } + + implicit def showMap[K,V](implicit sk: Show[K], sv: Show[V]): Show[Map[K,V]] = new Show[Map[K,V]] { + def show(m: Map[K, V]) = + "Map(" + m.map { case (k, v) => sk.show(k) + " -> " + sv.show(v) } .mkString (", ") + ")" + } + + implicit def showMapOfNothing: Show[Map[Nothing,Nothing]] = new Show[Map[Nothing,Nothing]] { + def show(m: Map[Nothing, Nothing]) = m.toString + } +} |