Reputation: 1094
I can't use patterns or folding, per the parameters of the assignment, of which this is a toy example of a particular approach to a larger problem.
When I run the code, I get a '0', naturally. So the question is, how do I get the final value of a_count?
fun num_counter(numbers: int list, a_number: int) =
let val count = 0
in
let fun count_num(numbers: int list, a_count: int) =
if null numbers
then 0
else if (hd numbers) = a_number
then count_num(tl numbers, count + 1)
else count_num(tl numbers, count)
in
count
end
end
Upvotes: 1
Views: 71
Reputation: 16105
You can write it shorter using a fold:
fun num_counter (numbers, a_number) =
let fun count (b_number, total) =
if a_number = b_number
then total + 1
else total
in foldl count 0 numbers
end
Here foldl
takes three arguments: the function count
that accumulates the result when visiting each number, b_number
in numbers
, the initial value for total
being 0
and the numbers to fold over, numbers
. When foldl
has visited the last number, it uses the last accumulation in total
as the result.
foldl
is itself defined like this:
fun foldl f e [] = e
| foldl f e (x::xr) = foldl f (f(x, e)) xr
Or you can filter
and take the length
which costs a bit more:
fun num_counter (numbers, a_number) =
length (filter (fn b_number => a_number = b_number) numbers)
Upvotes: 0
Reputation: 3910
There are several issues with your code:
count_num
is never called.0
instead of the result
you've acumulated so far (a_count
).a_count
that, as I
understood holds the number of occurences of a_number
and count
declared at the second line.Here is some correction to it:
fun num_counter(numbers: int list, a_number: int) = let
fun count_num(numbers: int list, count: int) =
if null numbers
then count (* reached the end of the list =>
returned the number of occurences computed *)
else if (hd numbers) = a_number
then count_num(tl numbers, count + 1)
else count_num(tl numbers, count)
in
count_num (numbers, 0) (* first call of count_num,
count initiated to 0 *)
end;
Also note that you can use pattern matching to enhance readability of your recursive function:
fun num_counter(numbers: int list, a_number: int) =
let fun count_num([], count) = count
| count_num(i :: tl, count) =
count_num(tl, if i = a_number then count + 1 else count)
in
count_num (numbers, 0)
end;
Upvotes: 2