プログラミング言語 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