[Haskell-beginners] Why ShowS?

Yitzchak Gale gale at sefer.org
Thu Aug 11 11:13:59 CEST 2011


Brandon Allbery wrote:
> Now, as to how useful it is... you'll note there isn't actually a lot of
> code out there that uses ShowS

I use it sometimes.

ShowS was the first and simplest, "pretty-printer" library.
A pretty-printer library is an alternative to big ugly monolithic
expressions for creating output.

Because it is based on function composition, ShowS makes
it easier to write in a nice combinator style. All of the early
pretty-printer libraries used function composition in this way.

It appears early library writers assumed that because of its
advantages, and also because of certain limitations of
early compilers, everyone would always use ShowS
instead of directly constructing Strings. So they used
ShowS for the types of showHex and showOct. In reality
ShowS never caught on, but it's not worth the trouble
to change those original types now.

> The simplistic show/read system uses it, but most other
> parsers and string generators use other mechanisms instead:
> Monad, Applicative, occasionally Arrow.

Recently the trend is to use "builders" based on Monoid
for fast rendering libraries. That style has some of the
advantages of ShowS, plus, unlike ShowS, it works
equally well with ByteString and Text.

While not the fastest or most featureful, ShowS still has the
advantages of being really simple to use, available directly
from the Prelude without any external library (and thus
a standard style, even though it isn't as popular as it
could be), and it generally has a pleasing simplifying
effect on the surrounding code. It also works absolutely
seamlessly with showHex and showOct :).

Any big expression of type String that starts with
"concat" followed by a long list of String expressions
is a good candidate for using ShowS instead.

Here is a simple example of how to use ShowS:

showPerson :: String -> Int -> Int -> String
showPerson name age shoeSize =
  concat [ "Name: ", name, ", Age: ", show age,
  ", Shoe size: ", show shoeSize]
...
putStrLn $ showPerson name age shoe

becomes, in the ShowS style:

showsPerson :: String -> Int -> Int -> ShowS
showsPerson name age shoeSize =
  ("Name: " ++) . (name ++) . (", Age: " ++) . shows age .
  (", Shoe size: " ++) . shows shoeSize
...
putStrLn $ showsPerson name age shoe ""

Regards,
Yitz



More information about the Beginners mailing list