I want to write a function that takes a filename as a string and a list of pairs of characters. This function must open the named file, read the contents of the file, and echo the characters to the screen. Any occurrence of a character in the first position of a pair must be echoed as the character in the second position of the pair. For example, an invocation such as fileSubst "inputFile" [(#"a", #"b"), (#"b", #"z")] will echo the contents of inputFile with all occurrences of the character a replaced by the character b and all occurrences of the character b replaced by character z.
fun fileSubst (fileName : string, []) = nil
| fileSubst (fileName, (a,b)::cs) = let
val stream = TextIO.openIn fileName
TextIO.input1 = fileSubst (fileName,cs) in if isSome a
then print(Char.toString(a)) else TextIO.print end ;
As @molbdnilo suggest, split this into several functions that might be useful in other contexts. You could divide this into one function that reads the file's content into a string,
a function that searches for the right mapping in a list of pairs of characters,
a variation of this function that returns the key as a default value,
and a function that maps each character in a string to another one,
You can then compose those to get one that operates on files. I'm not sure I would assume that a function call
fileSubst "foo.txt"
might read the file's content, perform the substitution and print the result to screen. Why wouldn't it write it back to file or return it as a string?Since there are so many things you can do with a file's content, you could also make a more generic file handling function,
Then for example,
By making generically useful functions you don't have to populate your library with highly specialized functions that are likely not going to be re-used much anyways.