プログラミング言語 Standard ML 入門 (問題の解答例)
15.2 テキスト入出力
問 15.1
入力ファイル名のリストと出力ファイル名を受け取り,与えられたすべての入力ファ
イルの内容を連結した内容を出力ファイルに書き出す関数
cat : string list -> string -> unit.
を定義せよ.
解答例 以下に定義例を示す。
local
open TextIO
in
fun copyStream ins outs =
if endOfStream ins then ()
else case input1 ins of
SOME c => (output1(outs,c);
copyStream ins outs)
| NONE => copyStream ins outs
fun cat L out =
let
val sources = map openIn L
val sink = openOut out
in
(foldl (fn (x,_) => copyStream x sink) () sources;
map closeIn sources;
closeOut sink)
end
end
問 15.2
指定されたファイルの文字数と行数をプリントする関数
wc : string -> unit
を定義せよ.
解答例 以下に定義例を示す。
local
open TextIO
in
fun wc file =
let
val ins = openIn file
fun count (l,c) =
if endOfStream ins then (l,c)
else case input1 ins of
SOME #"\n" => count (l+1, c+1)
| SOME _ => count (l, c+1)
| NONE => (l,c)
val (l,c) = count (0,0)
val _ = print (Int.toString l ^ " ")
val _ = print (Int.toString c ^ "\n")
val _ = closeIn ins
in
()
end
end
以下はSML#でのテスト実行例である
# wc "count.sml"; 20 503 val it = () : unit
問 15.3
filterFile 関数を用いて,ファイルの中の文字をすべて小文字に変換した
ファイルを作成する関数
lowerFile : string -> string -> unit
を定義せよ.
解答例 以下に定義例を示す。
fun lowerFile inf outf = filterFile Char.toLower inf outf
問 15.4
stdIn と stdOut を使用し,プロンプト文字 ? を
印字し,ユーザからの入力を受け取り,入力した文字をそのまま印字するプロ
グラム
echo : unit -> unit
を書け.
たとえば,以下のような動作をする.
- echo();
? abc
abc
? 1234;
1234;
? val it = () : unit
この例では,最後のプロンプトの後,ファイル終了文字を入力している.
解答例
fun echo () =
let
fun loop () =
(print "? ";
if TextIO.endOfStream TextIO.stdIn then ()
else
case TextIO.inputLine TextIO.stdIn of
SOME string => (print string; loop ())
| NONE => loop()
)
in
loop()
end