【问题标题】:OCaml variable countingOCaml 变量计数
【发布时间】:2014-03-22 04:31:45
【问题描述】:

我正在尝试实现以下目标:在特定索引处查找元素。

因此,如果我有一个 [5; 2; 3; 6] 列表并请求索引 2 处的元素,它将返回 3

let counter = 0;;
let increase_counter c = c + 1;;
let rec get_val x n = match x with
    [] -> -1
  | (h::t) ->
    if (counter = n) then
      h
    else
      increase_counter counter ; get_val t n
;;

但是这段代码给了我一个错误,说 -1 不是“单元”类型?

【问题讨论】:

    标签: ocaml


    【解决方案1】:

    正如 Jeffrey Scofield 所说,您应该编写 let counter = ref 0 以使 counter 可变。现在,您可以使用内置的incr 函数来增加它(相当于counter := !counter + 1),您将通过!counter 获得它的值。

    您的算法也存在问题:如果计数器等于n,则返回列表的头部...您的意思是:如果列表的头部等于n,则返回柜台。

    你的程序是:

    let counter = ref 0;;
    
    let rec get_val x n = match x with
        [] -> -1
      | (h::t) ->
        if (h = n) then
          !counter
        else
          begin incr counter ; get_val t n end
    ;;
    

    请注意,我在 else 块周围添加了 beginend,以便可以将其解释为指令序列。

    您的程序现在可以运行,但它不是使用 ocaml 解决此问题的最佳方法。

    你应该写类似的东西

    let get_val x n =
      let rec get_val_aux x n counter = match x with
        | [] -> -1
        | h :: _ when h = n -> counter
        | _ :: t -> get_val_aux t n (succ counter)
      in
        get_val_aux x n 0
    ;;
    

    在这里,我们向get_val_aux 函数添加一个参数,我们在每次调用时递增该参数。此函数嵌套在get_val 函数中,以隐藏此附加参数,该参数在第一次调用时以0 初始化。

    我们不使用if 语句,而是使用when 条件来知道何时找到元素,并添加一个新的案例来匹配最后一个案例(未找到)。请注意使用_ 通配符以避免未使用的变量。

    succ 函数(用于后继)仅将1 添加到其参数中。相当于counter + 1

    【讨论】:

      【解决方案2】:

      这段代码有很多问题。如果您暂时忽略当前的问题,那么您将 OCaml 变量视为命令式语言的变量。但是,OCaml 变量是不可变的。这个函数

      let increase_counter c = c + 1
      

      不改变任何变量的值。它只是返回一个比你给它的数字大的数字 1。

      当我输入你的代码时,我从顶层得到的唯一错误是这个表达式:

        increase_counter counter ; get_val t n
      

      编译器警告您应该执行; 之前的表达式,因为它的副作用。即,它应该几乎总是具有unit 类型。由于(正如我所说)您的函数 increase_counter 返回一个 int,编译器会就此向您发出警告。

      【讨论】:

      • OCaml 变量是不可变的,你不能改变它们的值! :-) 我会寻找另一种方法来做到这一点(也许是你函数的一个额外参数)。但是,如果您坚持使用命令式编程,则需要使用参考 (let counter = ref 0)。
      • 大声笑好的,谢谢。我已经习惯了命令式语言,我想不出任何其他方式。
      • 等一下,但是如果我让 x = 1 然后让 x = 5 和 print_int x 它打印 5 而不是 1,那么我不是在更改变量吗?
      • 没有改变了变量。您有两个具有相同名称的不同变量。旧变量仍然存在。有关详细信息,请参阅此 SO 页面:stackoverflow.com/questions/14440719/…
      猜你喜欢
      • 2019-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-12
      • 2012-05-21
      相关资源
      最近更新 更多