在OCaml中的每个递归调用中保持计数器

id2*_*677 4 ocaml functional-programming

我正在尝试编写一个函数,该函数返回v给定列表中传递值的索引x; -1如果没有找到.我尝试解决方案:

let rec index (x, v) =
    let i = 0 in
        match x with
        [] -> -1
        | (curr::rest) -> if(curr == v) then
                            i
                          else
                            succ i; (* i++ *)
                            index(rest, v)
;;
Run Code Online (Sandbox Code Playgroud)

这对我来说显然是错误的(每次都会返回-1),因为它会i在每次传递时重新定义.我有一些模糊的方法,在我的头脑中使用单独的功能,没有我现在可以写下来的.我知道这是所有编程中的常见模式,所以我的问题是,在OCaml中执行此操作的最佳方法是什么?

pad*_*pad 7

突变不是解决OCaml中的问题的常用方法.对于此任务,您应该使用递归并通过i在某些条件下更改索引来累积结果:

let index(x, v) =
    let rec loop x i =
        match x with
        | [] -> -1
        | h::t when h = v -> i
        | _::t -> loop t (i+1)
    in loop x 0
Run Code Online (Sandbox Code Playgroud)

另一件事是,使用-1作为例外情况并不是一个好主意.你可能会在某处忘记这个假设并将其视为其他指数.在OCaml中,最好使用option类型处理此异常,因此编译器强制您None每次都要处理:

let index(x, v) =
    let rec loop x i =
        match x with
        | [] -> None
        | h::t when h = v -> Some i
        | _::t -> loop t (i+1)
    in loop x 0
Run Code Online (Sandbox Code Playgroud)