返回OCaml中列表的第n个元素?

时间:2012-03-20 21:47:01

标签: list recursion functional-programming ocaml

我是Ocaml的新手,只是想确保如何执行一个简单的函数,比如使用递归函数返回列表的第n个元素?

原型如get_nth (list, n) int list * int -> int

例如get_nth ([1,2,3], 1) -> 2

谢谢

4 个答案:

答案 0 :(得分:13)

您可能不会注意到List module已经存在List.nth功能。

如果你想用递归来写它:

let rec get_nth = function
    | [], _ -> raise (Failure "get_nth")
    | _, n when n < 0 -> raise (Invalid_argument "get_nth")
    | x::_, 0 -> x
    | x::xs, n -> get_nth(xs, n-1)

答案 1 :(得分:5)

使用元组作为这样的参数在OCaml中并不常见。通常你会使用currying并定义你的函数:

let get_nth list n = ...

这将有签名'a list -> int -> 'a。另请注意,此处有一个'a参数,这意味着,没有任何理由将您的功能仅限于整数。

现在让我们看看问题。如果你想获得第0个元素,你的函数会是什么样子?

let get_nth list 0 = List.head list (* this is not actually valid in OCaml *)

现在如果你有一个函数从m个项目列表中获取第n个元素(NB n> m),你怎么能用这个函数来构建另一个函数,它从m的列表中得到第n + 1个元素+1元素?让n + 1个元素的函数为get_nth'

let get_nth' list n' = get_nth (List.tail list) (n'-1)

现在你需要做的就是将两者结合起来,你就完成了。我会把最后一部分留给你。

如果你遵循这个建议,你会得到比它必须更复杂的东西。但是,通过这种方式更容易理解发生的事情。

答案 2 :(得分:3)

(在我看来)不使用元组的更简单的解决方案可以是:

let rec get_nth mylist index = match mylist with
    | [] -> raise (Failure "empty list")
    | first::rest -> 
        if index = 0 then first 
        else get_nth rest (index-1)
;;

答案 3 :(得分:0)

我已阅读here,因为您不必使用Result,因此使用try ... with代替提出错误可能会更好。 (代码从@Omar编辑)

let rec get_nth mylist index = match mylist with
    | [] -> Error "empty list"
    | first::rest -> 
        if index = 0 then Ok first 
        else get_nth rest (index-1)
;;

let result [1; 2; 3] 2 in 
    match result with
    | Error reason -> print_string reason
    | Ok num -> print_int num
;;

ResultCore.Std的一部分,如果我正确的话。