SML/NJ: 将数字的数字提取到 int 列表中

SML/NJ: Extracting a number's digits into an int list

输入:仅包含 1 行整数的文本文件

输出:带有数字数字的 int 列表

这是我的代码:

fun parse file =
  let
    val input = TextIO.openIn file

    fun read_digits (NONE,acc) = rev acc
      | read_digits (SOME e,acc) =
        let
          val c = Option.valOf (e)
          val str = Char.toString c
          val digit = Option.valOf (Int.fromString str)
        in
          read_digits (TextIO.input1 input,digit::acc)
        end
  in
    read_digits (TextIO.input1 input,nil: int list)
  end

这是我收到的错误消息:

test.sml:14.11-14.55 Error: operator and operand don't agree [tycon mismatch]
  operator domain: char option option * int list
  operand:         TextIO.elem option * int list
  in expression:
    read_digits (TextIO.input1 input,digit :: acc)
test.sml:17.5-17.52 Error: operator and operand don't agree [tycon mismatch]
  operator domain: char option option * int list
  operand:         TextIO.elem option * int list
  in expression:
    read_digits (TextIO.input1 input,nil: int list)

uncaught exception Error
  raised at: ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
             ../compiler/TopLevel/interact/evalloop.sml:44.55
             ../compiler/TopLevel/interact/evalloop.sml:292.17-292.20

关于如何处理这个问题有什么建议吗?

否则,有没有人有更好的办法将文本文件中的数字提取到 int 列表中?

这里的第一个问题是 SOME e 中的 e 已经是一个 char,你不必 "unpack" 它与 valOf

第二个问题是,即使在您删除 valOf 之后(并且您的程序将进行类型检查),尝试从文件中读取数字也会导致像这样的 运行-time 错误:

$ cat digits.txt
12345
$ smlnj read_digits_from_file.sml
...
- parse "digits.txt";

uncaught exception Option
  raised at: Basis/Implementation/option.sml:17.25-17.31

这是由于行尾字符。要解决这个问题,您可以这样做:

fun parse file =
  let
    val input = TextIO.openIn file

    fun read_digits (NONE, acc) = acc (* end of stream *)
      | read_digits (SOME ch, acc) =
        let
          val str = Char.toString ch
        in
          case (Int.fromString str) of
              SOME digit => read_digits (TextIO.input1 input, digit::acc)
            | NONE => acc (* return on first non-digit *)
        end
  in
    rev (read_digits (TextIO.input1 input, []))  (* rev moved here *)

一个简单的测试:

- parse "digits.txt";
val it = [1,2,3,4,5] : int list