[project @ 1996-07-25 21:02:03 by partain]
[nofib.git] / real / mkhprog / Main.lhs
1 % Mkhprog.lhs - Haskell equivalent of mkprog
2
3 % @(#)Mkhprog.lhs       2.4 dated 92/06/23 at 15:37:01
4
5 % Crown Copyright 1992
6
7 \documentstyle[a4wide]{article}
8
9 \title{Mkhprog --- a Command line Parser Generator}
10 \author{N D North\\
11         National Physical Laboratory\\
12         Teddington, TW11 0LW, UK.\\
13         {\tt ndn\@seg.npl.co.uk}}
14
15 % Some macros lifted from elsewhere to make this more standalone.
16 \makeatletter
17 % INLINE PROGRAM CODE
18 %
19 % \prog{foo} sets its argument in typewriter font.
20 \def\prog#1{\ifmmode\mbox{\tt #1}\else{\tt #1}\fi}
21
22 % NEWVERBATIM (from iso.sty)
23 %
24 % \newverbatim{foo} creates a new environment, foo, which behaves exactly
25 % like the verbatim environment except that it is delimited by
26 % \begin{foo} ... \end{foo}.
27 % See the VERBATIM section of latex.tex for the inspiration behind this.
28 %
29 \def\newverbatim#1{\expandafter\def\csname #1\endcsname{%
30 \\@verbatim \frenchspacing\\@vobeyspaces \csname \@x#1verbatim\endcsname}
31 \expandafter\let\csname end#1\endcsname=\endtrivlist
32 \new\@xverbatim{#1}}
33
34 \begingroup \catcode `|=0 \catcode `[= 1
35 \catcode`]=2 \catcode `\{=12 \catcode `\}=12
36 \catcode`\\=12
37 |gdef|new\@xverbatim#1[
38 |expandafter|def|csname \@x#1verbatim|endcsname##1\end{#1}[##1|end[#1]]]
39 |endgroup
40 \makeatother
41
42 \newverbatim{haskell}
43
44 \begin{document}
45 \maketitle
46
47 \section*{Introduction}
48
49 This document is the source code for, and description of, \prog{mkhprog} ---
50 a Haskell program which generates the skeleton of other Haskell programs.
51 In particular, it generates the code needed to parse values passed to a
52 program from the command line.
53
54 Given the command line flags and associated values to be interpreted by
55 a program, \prog{mkhprog} produces a module containing a \prog{main}
56 function which acquires the command line, parses any flags and values
57 present, and passes the values to the main body of the Haskell program
58 for further processing.
59
60 \prog{mkhprog} can produce standard or ``literate'' Haskell, it can
61 generate a module with any desired name, and it can send its output
62 to the standard output or to a named file.
63
64 The body of this document describes how to use \prog{mkhprog} and then
65 gives the code which implements it.
66 Annexes describe auxiliary functions, the continuation style of programming
67 used, and give hints and tips on compilation and general matters.
68
69 \section{\prog{mkhprog} in use}
70
71 \subsection{Installation}
72 \prog{mkhprog} is distributed as a literate Haskell file, \prog{Mkhprog.lhs},
73 and a UNIX manual page, \prog{mkhprog.1}.
74 \prog{Mkhprog.lhs} is also a \LaTeX\ source file which documents the program
75 and its usage.
76
77 To install \prog{mkhprog}, compile \prog{Mkhprog.lhs} (converting it to
78 standard Haskell first if necessary, as described in Annex~\ref{convert})
79 and place the binary somewhere accessible.
80 You may also want to put the manual page in your local manual directory.
81
82 \subsection{Flags}
83 We will first describe the command line parameters interpreted by
84 \prog{mkhprog} itself, and then show how it treats the remainder of its
85 command line.
86 The program interprets the following flags:
87 \begin{description}
88 \item[\prog{-l}] produces a ``literate'' Haskell script in which all lines of
89     code begin with the characters \prog{"> "}.
90     This file is an example of a literate Haskell script.
91 \item[\prog{-m} {\em module\_name}] writes a module called {\em module\_name}
92     rather than the default name of \prog{Main}.
93 \item[\prog{-o} {\em file\_name}] writes output to {\em file\_name} rather than
94     the default of standard output.
95 \end{description}
96 The first command line flag which is not a member of the above set marks
97 the beginning of the flags to be interpreted by the generated program, which
98 we will now describe.
99
100 Programs generated by \prog{mkhprog} can interpret command line flags and
101 associated values of any Haskell type of class \prog{Text}.
102 To generate a program which interprets a flag \prog{-f} and a value of
103 type \prog{Foo}, we invoke \prog{mkhprog} as
104 \begin{verbatim}
105 mkhprog -f Foo
106 \end{verbatim}
107 We may then invoke the generated program as
108 \begin{verbatim}
109 prog -f "MkFoo 3 True"
110 \end{verbatim}
111 if \prog{MkFoo 3 True} is a valid item of type \prog{Foo} and \prog{Foo}
112 is an instance of the class \prog{Text}.
113
114 If the type associated with the flag is either \prog{Bool} or \prog{String}
115 then the generated program behaves in a special manner as follows:
116 \begin{description}
117 \item[\prog{Bool}] the program interprets the flag without any following
118 value, i.e. a program generated by
119 \begin{verbatim}
120 mkhprog -b Bool 
121 \end{verbatim}
122 is invoked simply as
123 \begin{verbatim}
124 prog -b 
125 \end{verbatim}
126 with no \prog{True} or \prog{False}.
127
128 You can produce programs which interpret a Boolean flag as a toggle
129 by invoking \prog{mkhprog} as:
130 \begin{verbatim}
131 mkhprog +b Bool 
132 \end{verbatim}
133 The generated program may then be called with either \prog{-b} or
134 \prog{+b} to set an internal value to \prog{False} or \prog{True}
135 respectively.
136
137 Boolean flags default to \prog{False}.
138
139 \item[\prog{String}] the program interprets the flag followed by an unquoted
140 string, i.e.
141 \begin{verbatim}
142 mkhprog -s String 
143 \end{verbatim}
144 generates a program which is invoked as
145 \begin{verbatim}
146 prog -s string 
147 \end{verbatim}
148 rather than
149 \begin{verbatim}
150 prog -s \"string\" 
151 \end{verbatim}
152 String flags default to \prog{""} (the empty string).
153 \end{description}
154
155 \subsection{Output}
156 This section shows the output from \prog{mkhprog} and the editing needed
157 to produce a compilable program from it.
158 If \prog{mkhprog} is invoked as
159 \begin{verbatim}
160 mkhprog -b Bool -s String -f Foo
161 \end{verbatim}
162 then the following output is produced:
163 \begin{verbatim}
164 module Main (main) where
165
166 defaultArgs :: Args
167 defaultArgs  =  MkArgs False "" ??
168
169 usage :: Dialogue
170 usage  =  appendChan stderr "Usage: prog [-b] [-s String] [-f Foo]" exit done
171
172 data Args  =  MkArgs Bool String Foo deriving ()
173
174 parse_args :: Args -> String -> Dialogue
175 parse_args (MkArgs x1 x2 x3) ('-':'b':rest)
176     =  readbool (parse_args (MkArgs True x2 x3)) rest
177 parse_args (MkArgs x1 x2 x3) ('-':'s':rest)
178     =  readstring (\str -> parse_args (MkArgs x1 str x3)) rest
179 parse_args (MkArgs x1 x2 x3) ('-':'f':rest)
180     =  readval reads (\val -> parse_args (MkArgs x1 x2 val)) rest
181 parse_args (MkArgs x1 x2 x3) ('-': _ :rest)
182     =  usage
183 parse_args (MkArgs x1 x2 x3)  rest  =  prog x1 x2 x3 (lines rest)
184
185 main :: Dialogue
186 main  =  getArgs exit (parse_args defaultArgs . unlines)
187
188 and auxiliary functions ...
189 \end{verbatim}
190 The first line simply gives the module header and says that \prog{main}
191 is being exported.
192 If \prog{mkhprog} had been invoked with the \prog{-m} flag, then the
193 module name would have been different.
194
195 Next comes the default value of the command line arguments.
196 This is near the beginning as the user will probably want to edit it.
197 Boolean flags default to \prog{False}, strings to the empty string and
198 anything else to \prog{??}.
199 The user will need to edit \prog{??} to a sensible value before
200 compilation.
201
202 The function \prog{usage} is also near the beginning as it too will
203 probably need editing.
204 This function is called in case of the command line flags being invalid
205 and writes to the standard error a template for how to call the generated
206 program.
207
208 The later parts of the program should not need editing and consist of:
209 \begin{itemize}
210 \item A declaration of the \prog{Args} data type, which is used to
211     carry information about command line flags.
212 \item The definition of \prog{parse\_args} which parses command line
213     flags and associated values, gives an error message on unrecognised
214     flags, and calls \prog{prog} when it hits a non-flag command line
215     argument.
216     \prog{prog} is then called with the values associated with the command
217     line flags (or the default if the flag was not present) and any
218     remaining command line arguments, split into a list of strings, one
219     per argument.
220 \item The definition of \prog{main}, which just acquires the command line,
221     puts it into a processable form,
222     and passes it to \prog{parse\_args}, with \prog{defaultArgs}.
223 \item Auxiliary functions for reading Booleans, strings and arbitrary
224     values from the command line arguments.
225     These are given in Annex~\ref{auxfns}.
226 \end{itemize}
227
228 \subsection{Compilation}
229 Before compilation, the user must perform a few tasks:
230 \begin{itemize}
231 \item Edit any instances of \prog{??} in the declaration of \prog{defaultArgs}
232     to sensible values.
233 \item Provide a definition of \prog{prog} to be called from
234     \prog{parse\_args}.
235 \item Ensure that any user-defined data types associated with flags are in
236     scope and are instances of the class \prog{Text}.
237 \end{itemize}
238 The user may also want to edit the definition of \prog{usage} to give a
239 more informative error message, though this is not essential.
240
241 After these changes, the program is ready for compilation.
242 The generated program is standard Haskell (version 1.1 or later)
243 and will compile on any
244 conforming implementation; some compilers have quirks which prevent
245 straightforward compilation, which are documented in Annex~\ref{quirks}.
246
247 \section{Command line parsing}
248
249 The functions which parse the command line are very similar to
250 those generated by \prog{mkhprog} itself.
251 Indeed they are edited from \prog{mkhprog} output.
252
253 The program starts with a module header which just exports \prog{main}.
254 \begin{haskell}
255
256 > module Main (main) where
257
258 \end{haskell}
259
260 The \prog{main} function acquires the command line arguments and passes
261 them to \prog{parse\_args}, together with their default values, encapsulated
262 in \prog{defaultEnv} (see Annex~\ref{env} for a description of the
263 environment).
264 \begin{haskell}
265
266 > main :: Dialogue
267 > main  =  getArgs exit (parse_args defaultEnv . unlines)
268
269 \end{haskell}
270
271 \prog{parse\_args e str} reads occurrences of \prog{-l}, \prog{-m} and
272 \prog{-o}, with any associated values, from \prog{str}, modifies the
273 environment \prog{e} appropriately and then passes the remainder of
274 the command line and the modified environment to \prog{next}.
275 \begin{haskell}
276
277 > parse_args :: Env -> String -> Dialogue
278 > parse_args (MkEnv x1 x2 x3) ('-':'l':rest)
279 >     =  readbool (parse_args (MkEnv True x2 x3)) rest
280 > parse_args (MkEnv x1 x2 x3) ('-':'m':rest)
281 >     =  readstring (\str -> parse_args (MkEnv x1 str x3)) rest
282 > parse_args (MkEnv x1 x2 x3) ('-':'o':rest)
283 >     =  readstring (\str -> parse_args (MkEnv x1 x2 (File str))) rest
284 > parse_args e rest  =  next (pairs (lines rest)) e
285
286 \end{haskell}
287
288 \prog{pairs} splits a list of strings into a list of pairs of
289 strings.
290 If the length of its argument is odd, it adds a dummy empty string,
291 which will cause an error to be flagged by \prog{next}.
292 \begin{haskell}
293
294 > pairs :: [String] -> [(String, String)]
295 > pairs []         =  []
296 > pairs (s:s':ss)  =  (s,s') : pairs ss
297 > pairs [s]        =  [("",s)]
298
299 \end{haskell}
300
301 \prog{next sps} checks whether the list of pairs of strings, \prog{sps},
302 forms valid command line input to \prog{mkhprog}.
303 If not, a message is printed and the program halts; otherwise \prog{mkprog}
304 is called to generate the program.
305 \begin{haskell}
306
307 > next :: [(String, String)] -> Cont
308 > next sps e | check sps  =  mkprog sps e
309 >            | otherwise  =  usage
310
311 \end{haskell}
312
313 \prog{check sps} checks whether the list of pairs of strings, \prog{sps},
314 forms valid command line input to \prog{mkhprog}.
315 This consists of checking that
316 each flag is of the form \prog{-c}, or is of the form \prog{+c}
317 with associated type \prog{Bool}, where \prog{c} is a character
318 and that none of the characters are duplicated.
319 \begin{haskell}
320
321 > check :: [(String, String)] -> Bool
322 > check sps  =  flags_ok sps && no_dups [flag | (_:flag:_,_) <- sps]
323 >               where
324 >               flags_ok  =  and . map f
325 >               f (['-',_],_)       =  True
326 >               f (['+',_],"Bool")  =  True
327 >               f _                 =  False
328 >               no_dups []      =  True
329 >               no_dups (c:cs)  =  not (c `elem` cs) && no_dups cs
330
331 \end{haskell}
332
333 \prog{usage} prints a message saying how \prog{mkhprog} should be used.
334 \begin{haskell}
335
336 > usage :: Dialogue
337 > usage
338 >     =  appendChan stderr
339 >        "Usage: mkhprog [-l] [-m module_name] [-o file_name] [[-flag type] ...]"
340 >        exit done
341
342 \end{haskell}
343
344 \prog{mkprog sps} generates and writes the program by calling a series of
345 functions, each generating one part.
346 \begin{haskell}
347
348 > mkprog :: [(String, String)] -> Cont
349 > mkprog sps
350 >     =  (do_header . nl . do_default types . nl . do_usage sps . nl
351 >         . do_datadecl types . nl . do_parse_args sps . nl . do_auxfns)
352 >        stop
353 >        where
354 >        types  =  map snd sps
355
356 \end{haskell}
357
358 \prog{do\_header} writes out the module header.
359 \begin{haskell}
360
361 > do_header :: Cont -> Cont
362 > do_header c
363 >     =  modname (\s -> writeln ("module " ++ s ++ " (main) where") c)
364
365 \end{haskell}
366
367 \prog{do\_default ts} writes a declaration for the default value of the
368 command line argument types, \prog{ts}.
369 \prog{String}s default to the empty string; Booleans default to \prog{False};
370 all other types default to \prog{??}, which must be edited to a sensible
371 value by the user.
372 \begin{haskell}
373
374 > do_default :: [String] -> Cont -> Cont
375 > do_default ts
376 >     =  writeln "defaultArgs :: Args"
377 >        . writeln ("defaultArgs  =  MkArgs" ++ concat (map f ts))
378 >        where
379 >        f "String"  =  " \"\""
380 >        f "Bool"    =  " False"
381 >        f _         =  " ??"
382
383 \end{haskell}
384
385 \prog{do\_usage sps} writes a usage function, which is called if the
386 command line arguments are invalid.
387 \begin{haskell}
388
389 > do_usage :: [(String, String)] -> Cont -> Cont
390 > do_usage sps
391 >     =  writeln "usage :: Dialogue"
392 >        . writeln ("usage  =  appendChan stderr \"Usage: prog"
393 >                   ++ concat (map f sps) ++ "\" exit done")
394 >        where
395 >        f (['-',c], "Bool")  =  " [-" ++ [c] ++ "]"
396 >        f (['+',c], "Bool")  =  " [(+|-)" ++ [c] ++ "]"
397 >        f (flag, typ)        =  " [" ++ flag ++ " " ++ typ ++ "]"
398
399 \end{haskell}
400
401 \prog{do\_datadecl ts} declares the type \prog{Args} to be made up of the
402 types \prog{ts}.
403 \begin{haskell}
404
405 > do_datadecl :: [String] -> Cont -> Cont
406 > do_datadecl ts
407 >     =  writeln ("data Args  =  MkArgs" ++ concat (map ((:) ' ') ts)
408 >                 ++ " deriving ()")
409
410 \end{haskell}
411
412 \prog{do\_parse\_args sps} writes the function which parses command line
413 arguments.
414 It applies \prog{do\_one\_flag} to each element of \prog{sps} and then
415 writes a final couple of clauses which catch invalid flags and call the
416 main program, \prog{prog}.
417 \begin{haskell}
418
419 > do_parse_args :: [(String, String)] -> Cont -> Cont
420 > do_parse_args sps
421 >     =  writeln "parse_args :: Args -> String -> Dialogue"
422 >        . foldr (.) end
423 >        (zipWith3 do_one_flag (repeat n) [1..] sps)
424 >        where
425 >        n  =  length sps
426 >        end  =  writeln (phead n ++ wildmatch '-' ++ "usage")
427 >                . writeln (phead n ++ " rest  =  prog" ++ args 1 n
428 >                           ++ " (lines rest)")
429 >                
430
431 \end{haskell}
432
433 \prog{do\_one\_flag n r sp} writes one clause of the function which
434 parses command line arguments.
435 \prog{n} is the arity of \prog{MkArgs}, \prog{r} is the number of the current
436 argument, \prog{sp} is a pair of the flag and its type (as strings).
437 \begin{haskell}
438
439 > do_one_flag :: Int -> Int -> (String, String) -> Cont -> Cont
440 > do_one_flag n r (['+',flag], _)
441 >     =  writeln (phead n ++ match '-' flag ++ do_readbool n r False)
442 >        . writeln (phead n ++ match '+' flag ++ do_readbool n r True)
443 > do_one_flag n r (['-',flag], "Bool")
444 >     =  writeln (phead n ++ match '-' flag ++ do_readbool n r True)
445 > do_one_flag n r (['-',flag], "String")
446 >     =  writeln (phead n ++ match '-' flag ++ do_readstring n r)
447 > do_one_flag n r (['-',flag], _)
448 >     =  writeln (phead n ++ match '-' flag ++ do_readval n r)
449
450 \end{haskell}
451
452 \prog{do\_auxfns} writes out the functions used by \prog{mkhprog} which
453 do not change from program to program.
454 The functions are described in Annex~\ref{auxfns}
455 \begin{haskell}
456
457 > do_auxfns :: Cont -> Cont
458 > do_auxfns
459 >     =    writeln "main :: Dialogue\n\
460 >                  \main  =  getArgs exit (parse_args defaultArgs . unlines)"
461 >        . nl
462 >        . writeln "readbool :: (String -> Dialogue) -> String -> Dialogue\n\
463 >                  \readbool f \"\"         =  f \"\"\n\
464 >                  \readbool f ('\\n':cs)  =  f cs\n\
465 >                  \readbool f _          =  usage"
466 >        . nl
467 >        . writeln "readstring :: (String -> String -> Dialogue) -> String \
468 >                                \-> Dialogue\n\
469 >                  \readstring f \"\"  =  f \"\" \"\"\n\
470 >                  \readstring f cs@(c:cs')\n\
471 >                  \    =  f s t\n\
472 >                  \       where\n\
473 >                  \       st      =  if c == '\\n' then cs' else cs\n\
474 >                  \       (s,t1)  =  span ((/=) '\\n') st\n\
475 >                  \       t       =  if t1 == \"\" then t1 else (tail t1)"
476 >        . nl
477 >        . writeln "readval :: (Read a) => ReadS a \
478 >                             \-> (a -> String -> Dialogue) -> String\n\
479 >                  \                       -> Dialogue\n\
480 >                  \readval readsfn f str\n\
481 >                  \    =  case thing of\n\
482 >                  \           []    -> usage\n\
483 >                  \           (_:_) -> f val (if str' == \"\" \
484 >                                             \then str' else (tail str'))\n\
485 >                  \       where\n\
486 >                  \       thing        =  readsfn str\n\
487 >                  \       (val, str')  =  head thing"
488
489 \end{haskell}
490
491 \prog{phead n} returns the first part of the \prog{parse\_args} function,
492 where \prog{n} is the arity of \prog{MkArgs}.
493 \begin{haskell}
494
495 > phead :: Int -> String
496 > phead n  =  "parse_args (MkArgs" ++ args 1 n ++ ") "
497
498 \end{haskell}
499
500 \prog{args a b} gives a sequence of argument name strings,
501 \prog{xa}, $\ldots$, \prog{xb}, separated by spaces.
502 \begin{haskell}
503
504 > args :: Int -> Int -> String
505 > args a b  =  concat [" x" ++ show r | r <- [a..b]]
506
507 \end{haskell}
508
509 \prog{match mp c} returns a pattern which matches against \prog{-c}
510 or \prog{+c} as \prog{mp} is \prog{'-'} or \prog{'+'}.
511 \begin{haskell}
512
513 > match :: Char -> Char -> String
514 > match mp c  =  "('" ++ [mp] ++ "':'" ++ [c] ++ "':rest)\n    =  "
515
516 \end{haskell}
517
518 \prog{wildmatch mp} returns a pattern which matches against \prog{-c}
519 or \prog{+c}, where \prog{c} is any character at all, as \prog{mp} is
520 \prog{'-'} or \prog{'+'}.
521 \begin{haskell}
522
523 > wildmatch :: Char -> String
524 > wildmatch mp  =  "('" ++ [mp] ++ "': _ :rest)\n    =  "
525
526 \end{haskell}
527
528 \prog{do\_readval}, \prog{do\_readstring} and \prog{do\_readbool} produce
529 pieces of code for reading arbitrary values, strings and booleans
530 respectively.
531 \begin{haskell}
532
533 > do_readval, do_readstring :: Int -> Int -> String
534 > do_readbool   :: Int -> Int -> Bool -> String
535 > do_readval n r     =  "readval reads (\\val -> " ++ bits n r "val"
536 > do_readstring n r  =  "readstring (\\str -> " ++ bits n r "str"
537 > do_readbool n r b  =  "readbool (" ++ bits n r (show b)
538
539 \end{haskell}
540
541 \prog{bits n r str} produces a handy part of \prog{parse\_args}.
542 \begin{haskell}
543
544 > bits :: Int -> Int -> String -> String
545 > bits n r str
546 >     =  "parse_args (MkArgs" ++ args 1 (r-1) ++ " " ++ str ++ args (r+1) n
547 >        ++ ")) rest"
548
549 \end{haskell}
550
551 \prog{writeln str} writes the string \prog{str} to the chosen
552 output channel, in  literate format if appropriate,
553 and then executes its continuation, \prog{c}.
554 \prog{nl} gives a newline on the standard output.
555 \begin{haskell}
556
557 > writeln :: String -> Cont -> Cont
558 > writeln str c
559 >     =  islit (\b ->
560 >        output (\f ->
561 >            let
562 >              str'   =  (if b then (lit str) else str) ++ "\n"
563 >              lit s  =  "> " ++ foldr ((++) . conv) "" s
564 >              conv '\n'  =  "\n> "
565 >              conv c     =  [c]
566 >            in
567 >               f str' exit . c))
568
569 > nl :: Cont -> Cont
570 > nl c  =  output (\f -> f "\n" exit . c)
571
572 \end{haskell}
573
574 \section{Miscellaneous}
575
576 \subsection{Bugs, comments and suggestions}
577 \prog{mkhprog} was written to implement one person's view of what a
578 skeleton Haskell program should look like.
579 It is by no means obvious that this is the best solution and any
580 suggestions for improvements are welcome.
581 Please send your bug reports, comments and suggestions to
582 \prog{ndn\@seg.npl.co.uk}.
583
584 \subsection{Acknowledgements}
585 \prog{mkhprog}'s functionality and manual page are closely based on those
586 of the C program \prog{mkprog}, whose author is unknown to me so I cannot
587 thank him or her in person.
588
589 Thanks also to the various implementers of Haskell around the world who
590 have borne with my continual bug reports and naive questions.
591 Thanks in particular to Will Partain who supplied useful patches to keep
592 \prog{mkhprog} in line with the changing definition of Haskell.
593
594 \appendix
595 \newpage
596 \section{Auxiliary functions}
597 \label{auxfns}
598
599 These are the functions produced by \prog{do\_auxfns}, which are used
600 by all programs written by \prog{mkhprog}.
601
602 \prog{readbool f str} checks that a Boolean flag is followed by either
603 newline or nothing: if it is, then \prog{f} is applied to the rest of
604 the string \prog{str}; if not, \prog{usage} is called.
605 \begin{haskell}
606
607 > readbool :: (String -> Dialogue) -> String -> Dialogue
608 > readbool f ""         =  f ""
609 > readbool f ('\n':cs)  =  f cs
610 > readbool f _          =  usage
611
612 \end{haskell}
613
614 \prog{readstring f str} reads a string, \prog{s}, from \prog{str} as follows:
615 \begin{itemize}
616 \item[] If \prog{str} begins with \verb|'\n'|, then \prog{s} is the
617     sequence of characters following the newline, up to the next newline
618     or the end of \prog{str}, whichever occurs first.
619 \item[] Otherwise \prog{s} is the initial substring of \prog{str}, up to
620     the first newline or the end of \prog{str}, whichever occurs first.
621 \end{itemize}
622 \prog{f} is then applied to \prog{s} and \prog{t}, where \prog{t} is the
623 remainder of \prog{str} after removing \prog{s} and a newline character, if
624 \prog{s} is followed by one.
625 \begin{haskell}
626
627 > readstring :: (String -> String -> Dialogue) -> String -> Dialogue
628 > readstring f ""  =  f "" ""
629 > readstring f cs@(c:cs')
630 >       =  f s t
631 >          where
632 >          st      =  if c == '\n' then cs' else cs
633 >          (s,t1)  =  span ((/=) '\n') st
634 >          t       =  if t1 == "" then t1 else (tail t1)
635
636 \end{haskell}
637
638 \prog{readval readsfn f str} reads a value from \prog{str} in the same manner
639 as \prog{readstring}, but the value can be of any type of class \prog{Text}.
640 The parameter \prog{readsfn} is the appropriate overloading of \prog{reads}
641 --- this parameter is not essential but, without it, \prog{readval} is
642 reliant on the ``monomorphic restriction'', whose future presence in
643 Haskell is not guaranteed.
644 \prog{f} is applied to the value and the remainder of \prog{str} as in
645 \prog{readstring}, but if no value can be read, \prog{usage} is called.
646
647 Since \prog{mkhprog} does not itself use \prog{readval}, its code does
648 not form part of this literate Haskell script.
649 \begin{verbatim}
650
651 readval :: (Read a) => ReadS a -> (a -> String -> Dialogue) -> String
652                        -> Dialogue
653 readval readsfn f str
654     =  case thing of
655            []    -> usage
656            (_:_) -> f val (if str' == "" then str' else (tail str'))
657        where
658        thing        =  readsfn str
659        (val, str')  =  head thing
660
661 \end{verbatim}
662
663 \section{Continuations and environments}
664
665 \subsection{Continuations}
666 \prog{mkhprog} is written in the continuation style, in which functions take
667 a continuation argument which tells the program ``what to do next''.
668 A continuation is a function which takes an environment parameter and gives
669 the rest of the program's output.
670 Thus we may define a data type for continuations thus:
671 \begin{haskell}
672
673 > type Cont  =  Env -> Dialogue
674
675 \end{haskell}
676
677 The null continuation, which does nothing, is
678 \begin{haskell}
679
680 > stop :: Cont
681 > stop e  =  done
682
683 \end{haskell}
684
685 \subsection{Environments}
686 \label{env}
687 An environment contains all the information needed to generate the output
688 program, viz.
689 \begin{enumerate}
690 \item Whether it is a literate program.
691 \item The name of the module to be generated.
692 \item Whether output is to \prog{stdout} or to a file and, if the latter,
693     the file's name.
694 \end{enumerate}
695 We may encompass this information in an environment data type:
696 \begin{haskell}
697
698 > data Env  =  MkEnv Bool String Output
699
700 \end{haskell}
701 Where the \prog{Bool} component is \prog{True} or \prog{False} as the
702 program is literate or not, the \prog{String} component is the module
703 name, and the \prog{Output} component gives details of the output stream
704 as follows:
705 \begin{haskell}
706
707 > data Output  =  Stdout | File String
708
709 \end{haskell}
710
711 The value of the environment is determined by the command line flags to
712 \prog{mkhprog}.
713 The default environment is
714 \begin{haskell}
715
716 > defaultEnv :: Env
717 > defaultEnv  =  MkEnv False "Main" Stdout
718
719 \end{haskell}
720
721 \subsection{Environment access}
722 Functions which need to access the environment use the
723 access functions in this section.
724
725 \prog{islit bc} applies \prog{bc} to the value of the Boolean
726 environment component.
727 \begin{haskell}
728
729 > islit :: (Bool -> Cont) -> Cont
730 > islit bc e@(MkEnv l _ _)  =  bc l e
731
732 \end{haskell}
733
734 \prog{modname sc} applies \prog{sc} to the string environment
735 component.
736 \begin{haskell}
737
738 > modname :: (String -> Cont) -> Cont
739 > modname sc e@(MkEnv _ m _)  =  sc m e
740
741 \end{haskell}
742
743 \prog{output oc} applies \prog{oc} to a function which writes its
744 argument to the output channel given by the \prog{Output} environment
745 component.
746 \begin{haskell}
747
748 > output :: ((String -> FailCont -> SuccCont -> Dialogue) -> Cont) -> Cont
749 > output oc e@(MkEnv _ _ Stdout)    =  oc (appendChan stdout) e
750 > output oc e@(MkEnv _ _ (File f))  =  oc (appendFile f) e
751
752 \end{haskell}
753
754 \section{Hints and tips}
755
756 \subsection{Compilation}
757 \label{quirks}
758 This section summarises the compilability of \prog{mkhprog} on the
759 compilers available at the time of writing (92/06/23).
760 \begin{description}
761 \item[Glasgow Prototype 0.41] Supports Haskell version 1.0, so
762     cannot compile this file.
763     Contact me if you want a version of \prog{mkhprog} that compiles under
764     Haskell version 1.0.
765 \item[Chalmers Haskell B 0.997.5] This file (\prog{Mkhprog.lhs}) compiles and
766     runs with no problems.
767     Command line parameters to \prog{mkhprog} and the programs it generates
768     must follow an isolated \prog{-},
769     as others are interpreted by the run-time system (see the documentation).
770 \item[Yale 1.0-0] The Yale system does not support \prog{getArgs} so
771     \prog{mkhprog} and the programs it generates are entirely useless on
772     this system.
773 \end{description}
774
775 \subsection{Extracting a standard Haskell program}
776 \label{convert}
777 \prog{mkhprog} is distributed as a literate Haskell script.
778 If your compiler is unable to compile such scripts, you should type
779 the following UNIX command line (assuming this file is called
780 \prog{Mkhprog.lhs}):
781 \begin{verbatim}
782 expand Mkhprog.lhs | sed -e "/^> /\!d" -e "s/^> //" > Mkhprog.hs
783 \end{verbatim}
784 The output file \prog{Mkhprog.hs} is then standard Haskell and can be
785 compiled in the normal way.
786
787 \subsection{Things with literate Haskell}
788 Those, like myself, who like their literate Haskell surrounded by a
789 \LaTeX\ environment may care to use something like this:
790 \begin{verbatim}
791 mkhprog -l <flags> | perl -pe 's/^$/\n\\end{haskell}\n\\begin{haskell}\n/' > Foo.hs
792 \end{verbatim}
793 The file \prog{Foo.hs} will then have its declarations placed within a
794 \LaTeX\ environment called \prog{haskell}.
795
796 \end{document}