I'm trying to create a List reading a text file, for example I have a text file like this "1 5 12 9 2 6" and I want to create a list like this [1,5,12,9,2,6] using SML
You can divide this task into several sub-problems:
Reading a file into a string can be done with
type filepath = string
(* filepath -> string *)
fun readFile filePath =
let val fd = TextIO.openIn filePath
val s = TextIO.inputAll fd
val _ = TextIO.closeIn fd
in s end
Converting a list of strings into a list of integers can be done with
(* 'a option list -> 'a list option *)
fun sequence (SOME x :: rest) = Option.map (fn xs => x :: xs) (sequence rest)
| sequence (NONE :: _) = NONE
| sequence [] = SOME []
fun convert ss = sequence (List.map Int.fromString ss)
Since any one string-to-integer conversion with Int.fromString may fail and produce a NONE, List.map Int.fromString will produce an "int option list" rather than an "int list". This list of "int option" may be converted to an optional "int list", i.e., remove the SOME of all the "int option", but if there's a single NONE, the entire result is discarded and becomes NONE. This gives the final type "int list option" (either NONE or SOME [1,2,...]).
You can divide this task into several sub-problems:
Reading a file into a string can be done with
See the
TextIOlibrary.Converting a string into a list of strings separated by whitespace can be done with
See the
String.tokensfunction.Converting a list of strings into a list of integers can be done with
Since any one string-to-integer conversion with
Int.fromStringmay fail and produce aNONE,List.map Int.fromStringwill produce an "int option list" rather than an "int list". This list of "int option" may be converted to an optional "int list", i.e., remove theSOMEof all the "int option", but if there's a singleNONE, the entire result is discarded and becomesNONE. This gives the final type "int list option" (eitherNONEorSOME [1,2,...]).See the
Option.mapfunction which was useful for this kind of recursion.Combining these,
This approach does yield some potentially unwanted behavior:
readIntegersthrow anIoexception~5inside the file will be interpreted as negative five-5will produce a failure (NONE)123awill produce the number 123 (Int.toStringis a bit too forgiving)You may want to address those.