Создать список с чтением файла с помощью SML - PullRequest
1 голос
/ 08 февраля 2020

Я пытаюсь создать список, читающий текстовый файл, например, у меня есть текстовый файл, подобный этому "1 5 12 9 2 6", и я хочу создать список, подобный этому [1,5,12,9,2,6], используя SML

1 Ответ

0 голосов
/ 10 февраля 2020

Вы можете разделить эту задачу на несколько подзадач:

  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
    

    См. the TextIO библиотека .

  2. Преобразование строки в список строк, разделенных пробелами, можно выполнить с помощью

    (* string -> string list *)
    fun split s =
        String.tokens Char.isSpace s
    

    См. the String.tokens функция .

  3. Преобразование списка строк в список целых чисел можно выполнить с помощью

    (* '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 option list", а не "int list". Этот список «int option» может быть преобразован в необязательный «int list», т. Е. Удалить SOME из всех «int option», но если существует один NONE, весь результат отбрасывается и становится NONE. Это дает окончательный тип «int list option» (NONE или SOME [1,2,...]).

    См. функцию Option.map , которая была полезна для такого рода рекурсии.

  4. Комбинируя их,

    (* filepath -> int list *)
    fun readIntegers filePath =
        convert (split (readFile filePath))
    

Этот подход приводит к потенциально нежелательному поведению:

  • Ошибки файловой системы readIntegers выбросить Io исключение
  • Строка ~5 внутри файла будет интерпретироваться как отрицательная пять
  • Строка -5 приведет к ошибке (NONE)
  • Строка 123a будет выдавать число 123 (Int.toString слишком простительно)

Возможно, вы захотите обратиться к ним.

...