Ocaml没有保留其值

时间:2016-12-03 06:21:26

标签: functional-programming ocaml ref

(* junk.ml *)
let flag = ref false

let get_flag = !flag

let play_cards card =
    Printf.printf "%s-clause\n" (if card >= 27 && card <= 39 then "true" else "false");
    (flag := if card >= 27 && card <= 39 then true else !flag);
    Printf.printf "check: %B  " get_flag;

在utop中,我导入了junk.ml并收到了此输出

val flag : bool ref = {contents = false} val get_flag : bool = false val play_cards : int -> unit = <fun>

我打电话给play_cards 30;;并收到了这个输出:

true-clause
                                                                   check: true - : unit = ()

然而,当我致电get_flag时,我收到了false。我想知道在编写这段代码时是否存在使用refs的概念。

2 个答案:

答案 0 :(得分:2)

您的变量get_flag!flag定义时的值的不可变名称。你不应该期望它的价值会发生变化; OCaml变量具有不可变的值。

(有些值,如flag,是本身可变的事物的不可变名称。换句话说,flag始终是同一引用的名称,但存储的值是引用!flag可以改变。)

您的评论表明您希望get_flag具有不同时间的不同值。获得此结果的一种方法是将其定义为函数:

let get_flag () = !flag

现在您可以调用该函数,并在每次调用时在调用时返回flag的值。

# let flag = ref false 
  let get_flag () = !flag;;
val flag : bool ref = {contents = false}
val get_flag : unit -> bool = <fun>
# get_flag ();;
- : bool = false
# flag := true;;
- : unit = ()
# get_flag ();;
- : bool = true

答案 1 :(得分:0)

如图所示,您的代码没有意义,hearts_brokenget_hearts_broken永远不会被定义。但是,如果你已经在其他地方做了这些定义,那么难怪你会看到你看到的结果,因为play_cards实际上并没有像你想象的那样修改flag。 / p>

我猜您在某个时候已将hearts_broken重命名为flag,但忘了修复play_cards?这恰好不会导致错误,因为你没有重新启动顶层,所以旧的定义仍然存在?