I am trying to write a recursive function that takes in a list as argument and returns the number of even and odd numbers in tuple (number_of_even, number_of_odd)
let rec countEvenOdd lst e o =
match lst with
| [] -> (e,o) (* Base case: empty list *)
| hd :: tl -> if hd mod 2 = 0 then countEvenOdd tl (e + 1) o else countEvenOdd tl e (o + 1)
;;
countEvenOdd [2;4;5;6;7;8];;
This just gives me the type:
- : int -> int -> int * int = <fun>
Because you've provided one argument to a function which expects three, you have partially applied the function, so you get a function back which takes the remaining two arguments.
This is a crucial elementary aspect of programming in OCaml: functions take one argument and return one value. That value returned may be a function itself.
In your specific case doubtless you meant to call countEvenOdd [2; 4; 5; 6; 7; 8] 0 0
but you can hide that implementation detail by shadowing countEvenOdd
.
let rec countEvenOdd lst e o =
match lst with
| [] -> (e,o) (* Base case: empty list *)
| hd :: tl ->
if hd mod 2 = 0 then countEvenOdd tl (e + 1) o
else countEvenOdd tl e (o + 1)
let countEvenOdd lst = countEvenOdd lst 0 0
Note, you might just make the accumulator a tuple rather than two arguments.
let rec countEvenOdd lst (e, o as acc) =
match lst with
| [] -> acc
| hd :: tl ->
if hd mod 2 = 0 then countEvenOdd tl (e + 1, o)
else countEvenOdd tl (e, o + 1)
Of course, this starts to look like a fold.
let countEvenOdd lst =
List.fold_left
(fun (e, o) x -> if x mod 2 = 0 then (e+1, o) else (e, o+1))
(0, 0)
lst