Example:
You have a pure function that may be giving you incorrect results.
> fib :: Int -> Int
> fib n | n < 2 = n
> | otherwise = fib (n-1) - fib (n-2)
>>> fib 3
0
Insert a call to @traceFunction@ to aid with debugging.
> fib, fib' :: Int -> Int
> fib = traceFunction "fib" fib'
> fib' n | n < 2 = n
> | otherwise = fib (n-1) - fib (n-2)
Calls to your pure function now provide its parameters and result as debugging information.
>>> fib 3
fib 1 = 1
fib 0 = 0
fib 2 = 1
fib 1 = 1
fib 3 = 0
0
Hopefully this will help you home in on your bug.
Note that @traceFunction@ works with functions of more than one parameter...
> traceElem :: Eq a => a -> [a] -> Bool
> traceElem = traceFunction "elem" elem
...and with \"functions\" of no parameters at all.
> alpha = traceFunction "Fine-structure constant" $ e * e * c * mu0 / 2 / h
Parameters and results must implement the 'Show' typeclass. As a special case, parameters may instead be
functions, and are shown as an underscore (@_@).
>>> :set -XNoMonomorphismRestriction
>>> let map' = traceFunction "map" map
>>> map' (2 *) [1..3]
map _ [1,2,3] = [2,4,6]
[2,4,6]
KNOWN BUG: The resultant function is strict, even when the input function is non-strict in some of its
parameters. In particular,
* if one of the parameters is @error \"foo\"@, the return value when the resultant function call is
evaluated will be @error \"foo\"@; no trace message will be output
* if one of the parameters doesn't terminate when evaluated, the resultant function call will not
terminate when evaluated either; no trace message will be output