是否在每个函数调用中都评估了可选参数的默认值?

问题描述 投票:1回答:1

OCaml spec记录了默认值在可选参数中的使用,但是没有指定默认值例如是每次可能返回不同值的函数。

经过一些测试,似乎每次if都没有传入参数时,都会对值进行求值;例如

let x = ref 0;;

let incr x =
  x := !x + 1;
  !x
;;

let test ?(a = incr x) () = a;;

调用test ()会导致1、2、3,...,每次递增,但是调用test ~a:123 ()不会使引用递增。

似乎运行test ()test ~a ()的行为大致类似于

let test ?a () =
  let a =
    match a with
    | None -> incr x
    | Some a -> a
  in
  body_of_test ~a ()
;;

这是建模的正确方法吗?而且,此行为是否记录在某处?

function ocaml optional-parameters
1个回答
0
投票

这确实是预期的行为。从documentation(强调我的)中查看:

fun ? lab :( pattern = expr0 ) -> expr形式的函数等效于fun ? lab : ident -> let pattern = match ident with Some ident -> ident | None -> expr0 in expr

其中ident是一个新鲜变量,除了在评估expr0时未指定,否则除外

尽管对增量的求值方法如您所愿,但在功能应用程序中“隐藏”效果是极不明智的。值得注意的是,下面的代码可能返回truefalse,但不能保证编译器的另一个版本会产生相同的行为。

let test2 ?(a = incr x) ?(b = incr x) () = a < b
if test2 () then ...
© www.soinside.com 2019 - 2024. All rights reserved.