gpt4 book ai didi

ocaml - OCaml 中的副作用和顶级表达式

转载 作者:行者123 更新时间:2023-12-04 21:59:42 29 4
gpt4 key购买 nike

我在使用 ocaml 时遇到了麻烦。

我想创建一个函数,每次调用它时都会增加我的计数器,并将我的 vargen 字符串与计数器编号连接起来,然后返回这个新字符串。

我没有成功的做法是:

let (counter : int ref) = ref 0;;
let (vargen : string) = "_t";;
let tmp = incr counter;ref (vargen ^ string_of_int !counter);;
Printf.printf "%s\n" !tmp;;
Printf.printf "%s\n" !tmp;;
Printf.printf "%s\n" !tmp;;
Printf.printf "%s\n" !tmp;;

但我的输出总是:
_t1
_t1
_t1
_t1

我的输出应该是:
    _t0
_t1
_t2
_t3

有什么想法可以解决我的问题 Guyz?

谢谢大家。

最佳答案

当你写 let tmp = ref foo , 表达式 foo被评估一次,以产生一个存储在引用中的值。访问引用会返回此值,而无需重新计算原始表达式。

引发重新评估的方法是使用函数代替:如果您编写函数 (fun () -> foo) ,这是一个值:它按原样返回,传递给函数,存储在引用中。每次将参数应用到该值时,表达式 foo被评估。

克莱门特的解决方案很好。的想法

let counter =
let count = ref (-1) in
fun () -> incr count; !count

是引用被分配一次,但每次增加函数 fun () -> incr count; !count叫做。具有函数的局部引用避免了全局变量的一些陷阱。您可以将其视为函数 counter 的“静态变量”。 ,只是它是 OCaml 范围和评估规则的自然结果,而不是附加的、特定于功能的概念。

你甚至可以写一个更通用的 vargen生成器,每次调用时都会创建新的独立计数器:
let make_vargen prefix =
let count = ref (-1) in
fun () ->
incr count;
prefix ^ string_of_int !count

let fresh_t = make_vargen "t"
let () = print_endline (fresh_t ()) (* t0 *)
let () = print_endline (fresh_t ()) (* t1 *)
let fresh_u = make_vargen "u"
let () = print_endline (fresh_u ()) (* u0 *)
let () = print_endline (fresh_t ()) (* t2 *)
let () = print_endline (fresh_u ()) (* u1 *)

关于ocaml - OCaml 中的副作用和顶级表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10459363/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com