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?
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?
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 show
ing 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.)
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