32

I have seen references to the showS trick to build strings (e.g., in this discussion), but I have never seen a good description of it.

What is the showS trick?

luispedro
  • 6,934
  • 4
  • 35
  • 45
  • 7
    Looking at the answers here, a concise summary might be: the "`showS` trick" is to turn an inefficient (`O(n^2)`) left-associated string concatenation into an efficient (`O(n)`) right-associated string concatenation by turning strings into (prepend) continuations and then composing the continuations. – ntc2 Dec 27 '13 at 01:11

2 Answers2

50

In the standard library, ShowS is defined as:

type ShowS = String -> String

This is a difference list. The trick is that a string xs is represented as a ShowS by the function that prepends it to any other list: (xs ++). This allows efficient concatenation, avoiding the problems of nested left-associative concatenation (i.e. ((as ++ bs) ++ cs) ++ ds). For example:

hello = ("hello" ++)
world = ("world" ++)

-- We can "concatenate" ShowS values simply by composing them:
helloworld = hello . world

-- and turn them into Strings by passing them an empty list:
helloworld' = helloworld ""

It's called ShowS because it's used in the implementation of the standard Show typeclass to allow efficient showing of large, deeply-nested structures; as well as show, you can implement showsPrec, which has the type:

showsPrec :: (Show a) => Int -> a -> ShowS

This allows handling of operator precedence, and returns a ShowS value. The standard instances implement this instead of show for efficiency; show a is then defined in terms of it, as showsPrec 0 a "". (This default definition is in the Show typeclass itself, so you can just implement showsPrec for a complete instance.)

ehird
  • 40,602
  • 3
  • 180
  • 182
  • 1
    Link: ShowS is in the Text.Show module of the base package at http://hackage.haskell.org/package/base-4.7.0.2/docs/Text-Show.html – James Brock Feb 02 '15 at 15:06
10

showS uses the difference list approach to efficiently concatenate individual components of the shown value. The function takes the value to be shown, and a string to append to the result. The appended string is passed all the way down to the right-most sub-value until it reaches a leaf, where it is actually appended.

There's a description of difference lists (including showS) here http://www.haskell.org/haskellwiki/Difference_list

pat
  • 12,587
  • 1
  • 23
  • 52