我刚接触Ocaml,想确认如何使用递归函数执行简单的功能,例如返回列表的第n个元素?
原型类似于get_nth (list, n)
,其中int list * int -> int
例如get_nth ([1,2,3], 1) -> 2
谢谢
我刚接触Ocaml,想确认如何使用递归函数执行简单的功能,例如返回列表的第n个元素?
原型类似于get_nth (list, n)
,其中int list * int -> int
例如get_nth ([1,2,3], 1) -> 2
谢谢
你可能没有注意到,但是 List.nth
函数已经在 List 模块 中存在。
如果你想使用递归来编写它:
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)
在OCaml中,像这样使用元组作为参数并不常见。通常你会使用柯里化(currying)并像这样定义函数:
let get_nth list n = ...
'a list -> int -> 'a
。还要注意,您在这里有一个'a
参数,这意味着没有真正的理由只限制函数为整数。let get_nth list 0 = List.head list (* this is not actually valid in OCaml *)
现在,如果你有一个函数用于从m个元素的列表中获取第n个元素(注意:n > m),那么你如何使用该函数构建另一个函数,以获取m+1个元素的第n+1个元素?让这个针对n+1个元素的函数为get_nth'
let get_nth' list n' = get_nth (List.tail list) (n'-1)
(依我之见) 不使用元组的更简单的解决方案是:
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)
;;
我在这里读到,使用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
;;
Result
是 Core.Std
的一部分,如果我没记错的话。