listrecursionfunctional-programmingocaml

# Trying to get the number of even and odd integers in a list

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>
``````

Solution

• 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
``````