我想从文件中读取一些数字,将它们带到列表中,最后在屏幕上显示它们。
numbers.txt目前有2 3 5 7 11
但是作为输出我正在获得11 7 5 3 2 - : unit = ()
为什么会这样?
let rec int_list_from_sb sb n =
match n with
| 0 -> [];
| _ -> (bscanf sb " %d" (fun a -> a))::(int_list_from_sb sb (n - 1));;
let file_name = open_in "numbers.txt" in
let sb = Scanning.from_channel file_name in
let int_list = int_list_from_sb sb 5 in
List.iter (fun a -> print_int a) int_list;;
答案 0 :(得分:5)
在OCaml中未指定参数的评估顺序。因此,当您执行f x :: g y
时,未指定是先调用f
还是g
。在您的情况下,在调用bscanf
之前调用递归调用,这就是您以错误的顺序得到结果的原因。
修复评估顺序问题的一般方法是在副作用的顺序很重要时将函数的参数放入局部变量中。因此,如果您希望f x :: g y
的效果在调用let fx = f x in fx :: g y
之前发生,那么您需要f x
而不是g
。
但是在你的情况下你可以像这样使用bscanf
的延续论证:
bscanf sb " %d" (fun a -> a :: int_list_from_sb sb (n - 1))