What is the showS trick in Haskell?
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
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.)