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?
The shows functions return a function that prepends the output String to an existing String . This allows constant-time concatenation of results using function composition.
(->) is often called the "function arrow" or "function type constructor", and while it does have some special syntax, there's not that much special about it. It's essentially an infix type operator. Give it two types, and it gives you the type of functions between those types.
The ++ operator is the list concatenation operator which takes two lists as operands and "combine" them into a single list.
Call by needHaskell is a well-known language that uses call-by-need evaluation.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With