Ocaml pattern matching issue

I am trying to write a simple recursive function that scans a list and returns a pair of integers. It is easy to write in c / C ++ / java, but I'm new to ocaml, so it’s somehow difficult to find a solution due to type conflict

It should look like.

let rec test pl = ... ;; val separate : ('a -> bool) -> 'a list -> int * int = <fun> test (fun x -> x mod 2 = 0) [-3; 5; 2; -6];; - : int * int = (2, 2) 

so the problem is how can I recursively return a value to a tuple.

+7
matching design-patterns ocaml
source share
2 answers

Partly from OCaml, but I think this will do the trick regarding REALFREE in the comment

 let rec test l = match l with [] -> (0,0) | x::xs -> if x > 0 then match (test xs) with (x,y) -> (x+1, y) else match (test xs) with (x,y) -> (x, y+1);; 

You can use nested matching statements to pull fragments of a tuple to change

EDIT: I did not know about the syntax of Pascal Quoc mentioned in his comment below, here is such code, it is more accurate and a little shorter:

 let rec test l = match l with [] -> (0,0) | x::xs -> if x > 0 then let (x,y) = test xs in (x+1, y) else let (x,y) = test xs in (x, y+1);; 

But the accepted answer is still much better, especially with tail recursion;).

+4
source share

One of the problems is that you return two different types: int for an empty list or a tuple otherwise. It must be one or the other.

Another problem is that you are trying to add 1 to test , but test is a function, not a value. You need to call a test for something else to return the value, but even then it should return a tuple that you cannot add to the integer.

I cannot understand what you want to do, but if you update your question with this information, I can help more.

Guess that I have what you want to count the positive numbers in the list, in which case you could write it like this:

 let rec test l = match l with [] -> 0 | x::xs -> if x > 0 then 1 + (test xs) else test xs;; 

Update : since you edited to clarify the problem, modify the above code as follows:

 let test l = let rec test_helper l pos nonpos = match l with [] -> (pos, nonpos) | x::xs -> if x > 0 then test_helper xs 1+pos, nonpos else test_helper xs pos 1+nonpos in test_helper l 0 0;; 

Using batteries helps in this case. It also makes tail-recursive, which is always good practice.

+5
source share

All Articles