我是Ocaml的新手,只是想确保如何执行一个简单的函数,比如使用递归函数返回列表的第n个元素?
原型如get_nth (list, n)
int list * int -> int
例如get_nth ([1,2,3], 1) -> 2
谢谢
答案 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
;;
Result
是Core.Std
的一部分,如果我正确的话。