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
输入:仅包含 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