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
1 回答
1
您可以将此任务分为几个子问题:
将文件读入字符串可以通过
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可以将字符串转换为由空格分隔的字符串列表
(* string -> string list *) fun split s = String.tokens Char.isSpace s可以将字符串列表转换为整数列表
(* '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)由于任何一个字符串到整数的转换
Int.fromString都可能失败并产生一个NONE,List.map Int.fromString将产生一个“int 选项列表”而不是“int 列表”。这个“int 选项”列表可以转换成一个可选的“int 列表”,即去掉SOME所有“int 选项”中的 ,但如果只有一个NONE,则整个结果被丢弃,变成NONE。这给出了最终类型“int 列表选项”(NONE或SOME [1,2,...])。请参阅对这种递归有用的
Option.map函数。结合这些,
(* filepath -> int list *) fun readIntegers filePath = convert (split (readFile filePath))
这种方法确实会产生一些可能不需要的行为:
- 文件系统错误将
readIntegers引发Io异常 - 文件内的字符串
~5将被解释为负五 - 该字符串
-5将产生失败 (NONE) - 该字符串
123a将产生数字 123 (Int.toString有点太宽容了)
您可能想要解决这些问题。
于 2020-02-10T15:45:02.650 回答