SML:如何使用ML在文件中编写两个列表

时间:2016-09-26 18:11:40

标签: io sml ml

此函数将一个实数列表写入文件:

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

1 个答案:

答案 0 :(得分:1)

首先,这是一些一般反馈:

  1. 这是attribute your sources的好习惯,在这种情况下会提供一些背景。

  2. 将许多实数写入文件的函数应该称为writeReals(复数)。

  3. 由于您放弃List.map的结果,请考虑使用List.app

  4.   

    如果我有两个列表,一个包含实数列表,另一个包含单词列表,如何读取和写入文件中的两个列表?

    • 我建议你实际写一个对列表,而不是一对列表。对列表,例如[(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
      
    • 写一个对列表,这里有一些提示:

      1. 编写一个函数pairToString : (real * string) -> string,将单个对转换为可写入文件的行。例如,pairToString (1.0, "Hello")应生成字符串"1.0 Hello\r\n"

      2. 使用上面的框架函数应用此函数:

        fun writeRealStringPairs (pairs, filename) =
            let val fd = TextIO.openOut filename
                val _ = List.app ... pairs
                val _ = TextIO.closeOut fd
            in () end
        

        用合理的东西替换...

    • 阅读配对列表,这里有一些提示:

      1. 编写一个函数pairFromString : string -> (real * string),将一行从文件转换为一对。例如,pairFromString "1.0 Hello\r\n"应生成(1.0, "Hello")对。

        这个函数被称为解析器,并不是完全无关紧要的。你可以幸运地使用函数String.tokens和... Char.isSpaceReal.fromString。请注意,Real.fromString实际上会返回 real option 类型的值,以防它失败,因此您需要使用例如模式匹配。

        case Real.fromString word1 of
             NONE   => raise Fail ("Couldn't parse as number: " ^ word1)
           | SOME r => r
        
      2. 将此功能应用于文件中的每一行,例如通过做:

        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
        

        用合理的东西替换...