【问题标题】:function returns list in reverse order in OCaml函数在 OCaml 中以相反的顺序返回列表
【发布时间】:2016-04-21 19:59:01
【问题描述】:

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

【问题讨论】:

    标签: ocaml


    【解决方案1】:

    OCaml 中未指定参数的评估顺序。因此,当您执行f x :: g y 时,未指定是先调用f 还是g。在您的情况下,递归调用是在调用 bscanf 之前调用的,这就是您以错误顺序获得结果的原因。

    解决求值顺序问题的一般方法是,当函数的副作用顺序很重要时,将函数的参数放入局部变量中。因此,如果您希望f x 的效果在调用g 之前发生,您可以使用let fx = f x in fx :: g y 而不是f x :: g y

    但是,在您的情况下,您可以像这样使用bscanf 的延续参数:

    bscanf sb " %d" (fun a -> a :: int_list_from_sb sb (n - 1))
    

    【讨论】:

    • 如果这里选择第二个函数,递归的,bscanf得到的整数会怎样?
    • @power_output 发生的情况是int_list_from_sb 4 求值,从sb 读取4 个数字并返回[7; 5; 3; 2],然后bscanf sb " %d" (fun a -> a) 求值并返回11,然后11 :: [7; 5; 3; 2] 被求值并返回[11; 7; 5; 3; 2]
    • @power_output 你很幸运,因为系统只是以可预测的方式推迟了扫描。结果可能(原则上)更有趣,因为sb 是一个可变结构:想象一下,如果两个表达式都被依次计算会发生什么。
    猜你喜欢
    • 1970-01-01
    • 2016-06-02
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-06
    • 2011-01-07
    相关资源
    最近更新 更多