gpt4 book ai didi

stream - OCaml:Stream.peek 不消耗线路?

转载 作者:行者123 更新时间:2023-12-02 09:17:18 25 4
gpt4 key购买 nike

我正在开发一个程序,该程序迭代输入文件,具有可变数量的“程序”,并以“0”结尾。如果我从文件顶部启动,我的函数运行工作正常,但由于某种原因,通过查看下一个字符是否为“0”(表示文件末尾)会消耗一行。

这是我的代码:

let line_stream_of_channel channel =
Stream.from
(fun _ ->
try Some (input_line channel) with End_of_file -> None);;

let in_channel = open_in "dull.in" in
let line_stream = line_stream_of_channel in_channel in
while Stream.peek line_stream != Some "0" do
run in_channel;
print_string "...\n";
done;;

根据我所读到的内容,Stream.peek 不应该消耗一行,所以也许问题不是由此而来,但如果不是,我无法弄清楚是什么在做它。有什么想法吗?

编辑这是我的整个程序:

let hello c = 
print_char c;;

let hello_int c =
print_int c;
print_char '\n';;

let ios = int_of_string;;

let rec print_string_list = function
[] -> print_string "\n"
| h::t -> print_string h ; print_string " " ; print_string_list t;;

let rec print_int_list = function
[] -> print_string "\n"
| h::t -> print_int h ; print_string " " ; print_int_list t;;

let rec append l i =
match l with
[] -> [i]
| h :: t -> h :: (append t i);;

let line_stream_of_channel channel =
Stream.from
(fun _ ->
try Some (input_line channel) with End_of_file -> None);;

let string_to_int_list str_list int_list=
let len = List.length str_list in
for i = 0 to len - 1 do
int_list := append !int_list (ios (List.nth str_list i));
done;;

let get_option = function
| Some x -> x
| None -> raise (Invalid_argument "Option.get");;

let chomp_line ns in_channel =
let s = input_line in_channel in
let len = String.length s in
let start_pos = ref 0 in
for i = 0 to len do
if i == len then
let word = String.sub s !start_pos (i - !start_pos) in
ns := append !ns word;
else if s.[i] == ' ' then
let word = String.sub s !start_pos (i - !start_pos) in
ns := append !ns word;
start_pos := i + 1;
done;;

let run in_channel =

let ns = ref [] in
chomp_line ns in_channel;
let n = ios (List.nth !ns 0) in
let p = ios (List.nth !ns 1) in
let s = ios (List.nth !ns 2) in
print_string "num dulls: "; hello_int n;
print_string "num programs: "; hello_int p;
print_string "num state transitions: "; hello_int s;

let dull_sizes = ref [] in
chomp_line dull_sizes in_channel;
let int_dull_sizes = ref [] in
string_to_int_list !dull_sizes int_dull_sizes;
print_string "size of dulls: "; print_int_list !int_dull_sizes;

let program_sizes = ref [] in
let program_dulls = ref [] in
for i = 0 to p - 1 do
let program = ref [] in
chomp_line program in_channel;
program_sizes := append !program_sizes (List.nth !program 0);
program_dulls := append !program_dulls (List.nth !program 1);
done;
let int_program_sizes = ref [] in
string_to_int_list !program_sizes int_program_sizes;
print_string "program sizes: "; print_int_list !int_program_sizes;
print_string "program dulls: "; print_string_list !program_dulls;

let transitions = ref [] in
chomp_line transitions in_channel;
let int_transitions = ref [] in
string_to_int_list !transitions int_transitions;
for i = 0 to s - 1 do
hello_int (List.nth !int_transitions i)
done
;;

let in_channel = open_in "dull.in" in
let line_stream = line_stream_of_channel in_channel in
while Stream.peek line_stream <> Some "0" do
run in_channel;
done;;

这是一个示例输入:

2 2 3
500 600
100 A
200 B
2 1 2
5 4 8
100 400 200 500 300
250 AC
360 ACE
120 AB
40 DE
2 3 4 -3 1 2 -2 1
0

最佳答案

(!=)是物理(指针)不等式,并且测试无法检测到您的结束标记 0 。当0被窥视,Stream.peek 返回 Some 0 ,但它与 Some 0 是不同的实体不等式检查的右手,因此循环永远不会终止,直到它在 EOF 处崩溃。

以下演示了正在发生的情况:

# Some 0 != Some 0;;
- : bool = true
# let x = Some 0 in x != x;;
- : bool = false

使用(<>) ,这里的结构性不平等。除了它和省略的run_in_channel部分,代码对我来说工作得很好。

黄金法则:不要使用 body 平等 (==)(!=)除非你真的需要它们。通常,坚持结构平等(=)(<>) .

--编辑--

代码中还有一个最初未公开的问题。

in_channel 创建流后。请勿自行触摸它,除非您想通过 close_in 关闭它!让流成为它的唯一读者。

流的好处是,一旦创建,您就无需关心实际读数何时发生。您仍然可以直接访问该 channel ,但这完全破坏了它的好处。只是不要这样做。使用Stream.nextStream.peek而不是input_line在你的run .

关于stream - OCaml:Stream.peek 不消耗线路?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22162715/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com