A small example: Reciprocation
For an example we have a program, called Recip.hs
, which computes
exact decimal representations of reciprocals, with recurring parts
indicated in brackets.
reciprocal :: Int -> (String, Int)
reciprocal n | n > 1 = ('0' : '.' : digits, recur)
| otherwise = error
"attempting to compute reciprocal of number <= 1"
where
(digits, recur) = divide n 1 []
divide :: Int -> Int -> [Int] -> (String, Int)
divide n c cs | c `elem` cs = ([], position c cs)
| r == 0 = (show q, 0)
| r /= 0 = (show q ++ digits, recur)
where
(q, r) = (c*10) `quotRem` n
(digits, recur) = divide n r (c:cs)
position :: Int -> [Int] -> Int
position n (x:xs) | n==x = 1
| otherwise = 1 + position n xs
showRecip :: Int -> String
showRecip n =
"1/" ++ show n ++ " = " ++
if r==0 then d else take p d ++ "(" ++ drop p d ++ ")"
where
p = length d - r
(d, r) = reciprocal n
main = do
number <- readLn
putStrLn (showRecip number)
main
HPC instrumentation is enabled with the -fhpc flag:
$ ghc -fhpc Recip.hs
GHC creates a subdirectory .hpc
in the current directory, and puts
HPC index (.mix
) files in there, one for each module compiled. You
don’t need to worry about these files: they contain information needed
by the hpc
tool to generate the coverage data for compiled modules
after the program is run.
$ ./Recip
1/3
= 0.(3)
Running the program generates a file with the .tix
suffix, in this
case Recip.tix
, which contains the coverage data for this run of the
program. The program may be run multiple times (e.g. with different test
data), and the coverage data from the separate runs is accumulated in
the .tix
file. To reset the coverage data and start again, just
remove the .tix
file.
Having run the program, we can generate a textual summary of coverage:
$ hpc report Recip
80% expressions used (81/101)
12% boolean coverage (1/8)
14% guards (1/7), 3 always True,
1 always False,
2 unevaluated
0% 'if' conditions (0/1), 1 always False
100% qualifiers (0/0)
55% alternatives used (5/9)
100% local declarations used (9/9)
100% top-level declarations used (5/5)
We can also generate a marked-up version of the source.
$ hpc markup Recip
writing Recip.hs.html
This generates one file per Haskell module, and 4 index files,
hpc_index.html
, hpc_index_alt.html
, hpc_index_exp.html
,
hpc_index_fun.html
.