【问题标题】:Trying to create a global variable in OCaml试图在 OCaml 中创建一个全局变量
【发布时间】:2021-03-01 00:38:50
【问题描述】:
let generateNextAssignList (assignList : (string * bool) list) : (string * bool) list * bool = 
  let carry = ref true in
  let flag = ref true in
  let inc_bools head =
    let (var, boolean) = head in 
    if (boolean = false && !flag = true) then
      (flag := false; carry := false; (var, Bool.not boolean))
    else if (boolean = true && !flag = true) then
      (var, Bool.not boolean)
    else
      (var, boolean) in
  (List.rev (List.map inc_bools (List.rev assignList)), !carry);;

generateNextAssignList [("a", true); ("a", true); ("a", false)];;

我希望在所有情况下都将!carry 设为false,除非传递给函数的列表是[],或者列表中每个元组中的布尔值都是true。到目前为止,当我使用该功能时,它工作正常,但!carry 始终是true,但在函数内部正确更新。有没有办法把它变成一个全局变量来解决这个问题?

【问题讨论】:

    标签: tuples global-variables ocaml ref


    【解决方案1】:

    问题是!carry 在元组的第一个元素之前被评估

    List.rev (List.map inc_bools (List.rev assignList)), !carry
    

    如果您需要强制执行副作用的顺序,最好添加明确的let

      let result = List.rev (List.map inc_bools (List.rev assignList)) in
      result, !carry
    

    (请注意,您的实现和规范之间存在差距:如果assignList 中的false 值的左侧有一个值,则进位为真。)

    但最好通过将算法一分为二来避免引用:

    • 首先将反向列表拆分为第一个假值
    • 根据第一个假值左边的元素个数计算进位
    • 创建结果列表:
    let generateNextAssignList assignList =
      let rec reverse_until_first_false rev = function
        | [] -> rev, []
        | (v, false) :: q -> (v,true) :: rev, q
        | (v, true) :: q -> reverse_until_first_false ((v, false) :: rev) q
      in
      let rev, rest = reverse_until_first_false [] (List.rev assignList) in
      let carry = match rest with [] -> true | _ -> false in
      let result = List.rev_append rest rev in
      result, carry
    

    【讨论】:

    • 谢谢!除了您在注释中指定的部分之外,您的实现似乎正在运行。为了澄清,我试图遍历列表中所有变量的所有可能排列(真假)(我以与二进制数相同的方式考虑它)。因此,一旦整个列表填充了 true [111],它就会将其设置回 [000] 并将“进位”值更改为 true,以指示已达到每个组合。
    • 您可以修复实现,方法是让 reverse_until_first_false 返回进位的值(即在 [] 情况下返回 true,在 (v,false)::_ 情况下返回 false。
    猜你喜欢
    • 2013-11-28
    • 2021-12-11
    • 2020-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多