此函数将一个实数列表写入文件:
fun writeReal (real, filename) =
let val fd = TextIO.openOut filename
val _ = map ( fn i => TextIO.output (fd, Real.toString i ^ "\r\n")) real
val _ = TextIO.closeOut fd
in () end
调用该函数:
writeReal ([1.0,2.0,3.0,4.0], "hello.txt")
将以下内容写入文件 hello.txt :
1.0
2.0
3.0
4.0
如果我有两个列表,一个包含实数列表,另一个包含单词列表,我如何读取和写入文件中的两个列表?例如:
writeReal ([1.0,2.0,3.0,4.0], [one, two, three, four] , "hello.txt")
应将以下内容写入文件 hello.txt :
1.0 one
2.0 two
3.0 three
4.0 four
答案 0 :(得分:1)
首先,这是一些一般反馈:
这是attribute your sources的好习惯,在这种情况下会提供一些背景。
将许多实数写入文件的函数应该称为writeReals
(复数)。
由于您放弃List.map
的结果,请考虑使用List.app
。
如果我有两个列表,一个包含实数列表,另一个包含单词列表,如何读取和写入文件中的两个列表?
我建议你实际写一个对列表,而不是一对列表。对列表,例如[(1.0, "Hello"), (2.0, "World")]
,将始终具有相同数量的实数和字符串。一对列表,例如([1.0, 2.0, 3.0], ["Hello", "World"])
不一定会有。
如果您被迫使用一对列表,您可以使用内置库函数ListPair.zip
将它们转换为对的列表,如下所示:
- ListPair.zip ([1.0, 2.0, 3.0], ["Hello", "World"]);
> val it = [(1.0, "Hello"), (2.0, "World")] : (real * string) list
写一个对列表,这里有一些提示:
编写一个函数pairToString : (real * string) -> string
,将单个对转换为可写入文件的行。例如,pairToString (1.0, "Hello")
应生成字符串"1.0 Hello\r\n"
。
使用上面的框架函数应用此函数:
fun writeRealStringPairs (pairs, filename) =
let val fd = TextIO.openOut filename
val _ = List.app ... pairs
val _ = TextIO.closeOut fd
in () end
用合理的东西替换...
。
阅读配对列表,这里有一些提示:
编写一个函数pairFromString : string -> (real * string)
,将一行从文件转换为一对。例如,pairFromString "1.0 Hello\r\n"
应生成(1.0, "Hello")
对。
这个函数被称为解析器,并不是完全无关紧要的。你可以幸运地使用函数String.tokens
和... Char.isSpace
和Real.fromString
。请注意,Real.fromString
实际上会返回 real option 类型的值,以防它失败,因此您需要使用例如模式匹配。
case Real.fromString word1 of
NONE => raise Fail ("Couldn't parse as number: " ^ word1)
| SOME r => r
将此功能应用于文件中的每一行,例如通过做:
fun isLinebreak c = c = #"\r" orelse c = #"\n"
fun readRealStringPairs filename =
let val fd = TextIO.openIn filename
val content = TextIO.inputAll fd
val _ = TextIO.closeIn fd
val lines = String.tokens isLinebreak content
val pairs = List.map ... lines
in pairs end
用合理的东西替换...
。