Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override toString of a scala type

Tags:

tostring

scala

I have a type in Scala:

  type Fingerprint = Seq[(Int, Int)]

I would like to override the toString of this type. How can I do this?

like image 335
Daniel Cukier Avatar asked Jan 24 '14 12:01

Daniel Cukier


People also ask

Can toString be overridden?

Override the toString() method in a Java Class A string representation of an object can be obtained using the toString() method in Java. This method is overridden so that the object values can be returned.

How do I override toString method in exception?

To display the message override the toString() method or, call the superclass parameterized constructor bypassing the message in String format. Then, in other classes wherever you need this exception to be raised, create an object of the created custom exception class and, throw the exception using the throw keyword.


2 Answers

There are good reasons to use a type class-based approach to this kind of problem instead of Scala's toString (which is arguably just an unpleasant hand-me-down from Java), and the fact that you can't bolt a toString on an arbitrary type is one of them. For example, you could write the following using Scalaz's Show type class:

import scalaz._, syntax.show._

implicit val fingerprintShow: Show[Fingerprint] = Show.shows(
  _.map(p => p._1 + " " + p._2).mkString("\n")
)

And then:

scala> Seq((1, 2), (3, 4), (5, 6)).shows
res0: String = 
1 2
3 4
5 6

There are also good reasons to prefer a type class-based approach to one based on implicit classes or other implicit conversions—type class instances are generally much easier to reason about and debug.

like image 141
Travis Brown Avatar answered Oct 04 '22 20:10

Travis Brown


Overriding toString may not be the best option here, but there is a simple alternative:

implicit class SeqAug[T <: (_, _)](val seq: Seq[T]) {
   def showInfo: String = {
      seq.map(p => p._1 + " " + p._2).mkString("\n") // or whatever you want.
   }
}
val x = Seq(("test" -> 5))
Console.println(x.showInfo)

You can even restrict the bound of the augmentation:

type Fingerprint = Seq[(Int, Int)]
implicit class SeqAug(val fingerprint: Fingerprint) {
  // same thing
}
like image 24
flavian Avatar answered Oct 04 '22 21:10

flavian