Return nth list item in OCaml?

I am new to Ocaml, I just want to make sure how to execute a simple function, for example, return the nth element of a list using a recursive function?

A prototype of type get_nth (list, n) with int list * int -> int

for example get_nth ([1,2,3], 1) -> 2

thanks

+7
source share
4 answers

You may not notice, but the List.nth function already exists in the List of modules .

If you want to write it using recursion:

 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) 
+11
source

Using tuples as parameters like this is common in OCaml. Usually you use currying and define your function as follows:

 let get_nth list n = ... 

This would have the signature 'a list -> int -> 'a . Also note that there is a 'a parameter here, which means there is no reason to restrict your function to ints only.

Now let's look at the problem. If you want to get a null element, what would your function look like?

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

now if you have a function to get the nth element from a list of m elements (NB n> m), how could you use this function to create another function that gets the n + 1st element from a list of m + 1 element? Let this function for n + 1 elements be get_nth'

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

Now all you have to do is combine the two, and you're done. I will leave this last part to you.

If you follow this advice, you will get something more complex than it should be. However, it is easier to understand what is going on along this path.

+4
source

(In my opinion) A simpler solution without using a tuple could be:

 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
source

I read here that using Result instead of raising an error might be nicer, since you don't need to use try ... with . (Code edited by @Omar Mahili)

 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 is part of Core.Std , if I'm right.

0
source

All Articles