创建一个使用SML读取文件的列表

创建一个使用SML读取文件的列表,sml,polyml,Sml,Polyml,我试图创建一个读取文本文件的列表,例如,我有一个这样的文本文件“1 5 12 9 2 6”,我想创建一个这样的列表[1,5,12,9,2,6]使用SML可以将此任务划分为几个子问题: 将文件读入字符串可以通过 type filepath = string (* filepath -> string *) fun readFile filePath = let val fd = TextIO.openIn filePath val s = TextIO.inputA

我试图创建一个读取文本文件的列表,例如,我有一个这样的文本文件
“1 5 12 9 2 6”
,我想创建一个这样的列表
[1,5,12,9,2,6]
使用SML

可以将此任务划分为几个子问题:

  • 将文件读入字符串可以通过

    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)
    

  • 将字符串转换为由空格分隔的字符串列表可以通过

    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)
    

  • 将字符串列表转换为整数列表可以通过

    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 option”列表可转换为可选的“int list”,即删除所有“int option”中的
    部分
    ,但如果只有一个
    ,则整个结果将被丢弃并变为
    。这给出了最后一种类型“int list option”(要么
    NONE
    要么
    SOME[1,2,…]

    看看哪一个对这种递归有用

  • 结合这些,

    (* filepath -> int list *)
    fun readIntegers filePath =
        convert (split (readFile filePath))
    
  • 这种方法确实会产生一些可能不需要的行为:

    • 文件系统错误将导致
      readIntegers
      引发
      Io
      异常
    • 文件中的字符串
      ~5
      将被解释为负5
    • 字符串
      -5
      将产生故障(
      NONE
    • 字符串
      123a
      将产生数字123(
      Int.toString
      有点过于宽容)
    您可能需要解决这些问题