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
问问题
270 次
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 回答