As you have stated, you just have to use the previous function number_in_month. Remembering that number_in_month takes a list of dates and a single month, and returns the number of matching months in the list of dates. Thus All there is needed to create number_in_months, is to call number_in_month for each element in the new list of months, with the original list of dates to be checked.
Such a solution could look like
fun number_in_months (dates, months) =
if null months then
0
else
number_in_month(dates, hd months) + number_in_months(dates, tl months)
However when you use pattern matching, you can shorten it down and make it even more readable
fun number_in_months (dates, []) = 0
| number_in_months (dates, d::ds) =
number_in_month(dates, d) + number_in_months(dates, ds)
There is absolutely no reason for creating a count function, carrying around a "state". This seems to be your imperative mind, at play :)
Take for example this simple function which will sum all element of a list
fun sum [] = 0
| sum (x::xs) = x + sum xs
or even creating a length function (which is actually similar to your count function)
fun length [] = 0
| length (x::xs) = 1 + length xs
Instead of repeating a lot of good stuff already mentioned so many times, I encouraging you to go read these questions and their answers.
Update
I also wanted to show you how to format you code in a better way
fun number_in_month (datelist : (int*int*int) list, month : int) =
let
fun count (x : int , datelist : (int*int*int) list) =
if null (tl datelist)
then x
else if #2(hd datelist) = month
then count (x+1, tl datelist)
else count (x, tl datelist)
in
if #2(hd datelist) = month
then count (1, datelist)
else count (0, datelist)
end
fun number_in_months (datelist : (int*int*int) list, monthlist : int list)=
let
fun count (x : int, monthlist : int list)=
if null (tl monthlist)
then x
else count (x + number_in_month(datelist, hd monthlist), tl monthlist)
in
count (number_in_month (datelist, hd monthlist), tl monthlist)
end
How to format nested if's is always a great debate where I'm from. Personally I avoid them, and use cases instead but I guess you will lean about that in the future.
However I also spotted a mistake in your count function. When you test whether your second argument (in both of your count functions) are the empty list with null, you do it on the tail of the argument, which will fail if the argument is in fact the empty list
- null (tl []);
uncaught exception Empty
For example this imput
- number_in_months ([(1,1,1)], [1]);
uncaught exception Empty
Also your logic in number_in_month is wrong, as you are testing for the head of the datelist being equal to month, however your to count in either case uses the whole of datelist instead of its tail. This is seen as the below should not return 2 as a result
- number_in_month([(1,1,1), (2,2,2), (3,3,3)], 1);
val it = 2 : int
This error, is the only thing that is making the number_in_month function not throwing up an exception.