函数在OCaml中以相反的顺序返回列表

时间:2016-04-20 14:09:04

标签: ocaml

我想从文件中读取一些数字,将它们带到列表中,最后在屏幕上显示它们。 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;;

1 个答案:

答案 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))