Show
API Documentation: Show
Show is an alternative to the Java toString
method.
It is defined by a single function show
:
def show(a: A): String
You might be wondering why you would want to use this, considering toString
already serves the same purpose and case classes already provide sensible implementations for toString
.
The difference is that toString
is defined on Any
(Java's Object
) and can therefore be called on anything, not just case classes.
Most often, this is unwanted behaviour, as the standard implementation of toString
on non case classes is mostly gibberish.
Consider the following example:
(new {}).toString
// res0: String = "repl.MdocSession$MdocApp$$anon$1@5c6e172f"
The fact that this code compiles is a design flaw of the Java API.
We want to make things like this impossible, by offering the toString
equivalent as a type class, instead of the root of the class hierarchy.
In short, Show
allows us to only have String-conversions defined for the data types we actually want.
To make things easier, Cats defines a few helper functions to make creating Show
instances easier.
/** creates an instance of Show using the provided function */
def show[A](f: A => String): Show[A]
/** creates an instance of Show using object toString */
def fromToString[A]: Show[A]
These can be used like this:
import cats.Show
case class Person(name: String, age: Int)
implicit val showPerson: Show[Person] = Show.show(person => person.name)
// showPerson: Show[Person] = cats.Show$$$Lambda$12949/0x00007fe45c2f0500@7c7d6130
case class Department(id: Int, name: String)
implicit val showDep: Show[Department] = Show.fromToString
// showDep: Show[Department] = cats.Show$$$Lambda$11987/0x00007fe45bff96d0@283f8832
This still may not seem useful to you, because case classes already automatically implement toString
, while show
would have to be implemented manually for each case class.
Thankfully with the help of a small library called kittens a lot of type class instances including Show
can be derived automatically!
Cats also offers Show
syntax to make working with it easier.
This includes the show
method which can be called on anything with a Show
instance in scope:
import cats.syntax.all._
val john = Person("John", 31)
// john: Person = Person(name = "John", age = 31)
john.show
// res1: String = "John"
It also includes a String interpolator, which works just like the standard s"..."
interpolator, but uses Show
instead of toString
:
val engineering = Department(2, "Engineering")
// engineering: Department = Department(id = 2, name = "Engineering")
show"$john works at $engineering"
// res2: String = "John works at Department(2,Engineering)"