| Elements of ML Programming, 2nd Edition (ML97) |
fun xPrint1(0,s) = print(s)
| xPrint1(n,s) = xPrint1(n-1, s^s);
fun xPrint(n) = (xPrint1(n,"X"),
print("\n")
);
Notice that xPrint1 counts down in its first argument, as it
doubles the length of its second argument.
Thus, when started as in the third line, with first argument n
and a second argument consisting of one X, by the time the first
argument is down to 0, the length of the second argument is 2^n.
That is the string that gets printed at line 1.
Technically, we are not required to retain the returned instream. However, if we do not bind it to some identifier, such as IN here, the token representing the instream is lost forever.
closeIn(in1);
This and subsequent solutions assume that structure TextIO is
already open.
val newLine = inputLine(in3);
fun howMany1(infile,i) =
if not (canInput(infile,i+1)) then i
else howMany(infile,i+1);
fun howMany(infile) = howMany1(infile, 0);
Here, howMany1(infile,i) is an auxiliary that recursiively
tries canInput with limits of i, i+1, and so on,
until it finds that i for which there are exactly i
characters waiting.
A call by howMany
to howMany1 with second argument 0 allows the exact
number of waiting characters to be determined.
open TextIO;
(* test if a character is white space *)
fun white(" ") = true
| white("\t") = true
| white("\n") = true
| white(_) = false
fun getWord(file) = (* read one word *)
if endOfStream(file) then ""
else
let
val c = inputN(file,1)
in
if white(c) then ""
else c^getWord(file)
end;
fun getList1(file) = (* read all words from an instream *)
if endOfStream(file) then nil
else getWord(file) :: getList1(file);
(* read all words from a file given the file name *)
fun getList(filename) = getList1(openIn(filename));
Download this program
val OUT = openAppend("/usr/spool/mail/fred");
This and the following solution assume that TextIO is already
open.
output(out2, "super");
(* read digits until a nondigit and return their value
assuming i is value of previously read digits
of digits *)
fun getInt(i,IN) =
if not (isSome(TextIO.lookahead(IN))) then
i (* end of file reached *)
else
let
val c = valOf(TextIO.input1(IN))
in
if c <= #"9" andalso c >= #"0" then (* c is a digit *)
getInt(10*i+ord(c)-ord(#"0"),IN)
else i
end;
(* print integer i in decimal *)
fun putInt1(i,OUT) =
if i<10 then
TextIO.output(OUT, str(chr(i+ord(#"0"))))
else (
putInt1(i div 10, OUT); (* print all but the last digit *)
putInt1(i mod 10, OUT) (* print the last digit *)
);
(* print i, surrounding multidigit numbers by parens *)
fun putInt(i,OUT) =
if i<10 then
putInt1(i,OUT)
else (
TextIO.output(OUT,"(");
putInt1(i,OUT);
TextIO.output(OUT,")")
);
(* convert i to a sequence of base-b digits and print *)
fun convert1(i,b,OUT) =
if i<b then putInt(i,OUT) else (
convert1(i div b, b, OUT);
putInt(i mod b, OUT)
);
(* read i and b and print i in base b *)
fun convert(IN,OUT) =
let
val i = getInt(0,IN);
val b = getInt(0,IN)
in
convert1(i,b,OUT)
end;
Download this program