A recursive function that returns all the values ​​in a list (in OCaml)

I need a function that recursively returns (does not print) all the values ​​in the list with each iteration. However, every time I try to do programming, my function returns a list.

let rec elements list = match list with | [] -> [] | h::t -> h; elements t;; 

I need to use each element every time it returns in another function that I wrote, so I need these elements one at a time, but I can not understand this part. Any help would be appreciated.

+4
source share
2 answers

Your function is equivalent to:

 let rec elements list = match list with | [] -> [] | h :: t -> elements t 

This is because a ; b a ; b evaluates a (and discards the result), and then evaluates and returns b . Obviously, this, in turn, is equivalent to:

 let elements (list : 'a list) = [] 

This is not a very useful feature.

However, before trying to solve this problem, please understand that Objective Caml functions can only return one value . Returning more than one value is not possible.

There are ways around this limitation. One solution is to pack all the values ​​that you want to return into one value: a tuple or a list, as a rule. So, if you need to return an arbitrary number of elements, you must collect them together in a list and process the code of the calling code:

 let my_function () = [ 1 ; 2; 3; 4 ] in (* Return four values *) List.iter print_int (my_function ()) (* Print four values *) 

Another less frequent solution is to provide a function and call it for each result:

 let my_function action = action 1 ; action 2 ; action 3 ; action 4 in my_function print_int 

This is less flexible, but perhaps faster than list return: lists can be filtered, sorted, saved ...

+3
source

Your question is confused - you need a function that returns all the values ​​in a list. Well, the easiest way to return a variable number of values ​​is a list! Perhaps you are trying to imitate Python generators? OCaml has nothing like yield , but instead, it usually does the same thing by β€œpassing” the function to a value (using iter , fold or map ).

What you have written currently is equivalent to this in Python:

 def elements(list): if(len(list) == 0): return [] else: list[0] return elements(list[1:]) 

If you are trying to do this:

 def elements(list): if(len(list) > 0): yield list[0] # this part is pretty silly but elements returns a generator for e in elements(list[1:]): yield e for x in elements([1,2,3,4,5]): dosomething(x) 

The equivalent in OCaml would be:

 List.iter dosomething [1;2;3;4;5] 

If you are trying to determine if list a is a subset of list b (as I have already compiled from your comments), you can use List.mem and List.for_all :

 List.for_all (fun x -> List.mem xb) a 

fun x -> List.mem xb defines a function that returns true if x is equal to any element in (is a member) b. List.for_all accepts a function that returns a bool (in our case, only a membership determination function) and a list. It applies this function to every item in the list. If this function returns true for each value in the list, then for_all returns true.

So what we did: for all elements in check if they are a member of b. If you're curious about how to write these functions yourself, I suggest reading the source of the .ml list, which (suppose * nix) is probably in / usr / local / lib / ocaml or / usr / lib / ocaml.

+1
source

Source: https://habr.com/ru/post/1335383/


All Articles