Reputation: 4396
I'm trying to write a simple recursive function that look over list and return a pair of integer. This is easy to write in c/c++/java but i'm new to ocaml so somehow hard to find out the solution due to type conflict
it should goes like ..
let rec test p l = ... ;;
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 value on tuple ..
Upvotes: 7
Views: 4388
Reputation: 7976
Been away from OCaml for a bit, but I think this will do the trick in regards to REALFREE's description 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 used the nested match statements to pull out pieces of the tuple to modify
EDIT: I didn't know about the syntax Pascal Cuoq mentioned in his comment below, here's the code like that, it's neater 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 the tail recursion ;).
Upvotes: 4
Reputation: 83250
One problem here is that you are returning two different types: an int for an empty list, or a tuple otherwise. It needs to 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 test on something else for it to return a value, but even then it is supposed to return a tuple, which you can't add to an integer.
I can't figure out what you want the code to do, but if you update your question with that info I can help more.
One guess that I have is that 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've 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 the accumulators help a lot in this case. It also makes the function tail-recursive which is always good practice.
Upvotes: 5