正如你所说,你只需要使用前面的函数number_in_month。请记住,number_in_month 需要一个日期列表和一个月份,并返回日期列表中匹配的月份数。因此,创建number_in_months 所需要做的就是为新月份列表中的每个元素调用number_in_month,并检查原始日期列表。
这样的解决方案可能看起来像
fun number_in_months (dates, months) =
if null months then
0
else
number_in_month(dates, hd months) + number_in_months(dates, tl months)
但是,当您使用模式匹配时,您可以将其缩短并使其更具可读性
fun number_in_months (dates, []) = 0
| number_in_months (dates, d::ds) =
number_in_month(dates, d) + number_in_months(dates, ds)
绝对没有理由创建一个带有“状态”的count 函数。这似乎是你的当务之急,在玩:)
以这个简单的函数为例,它将对列表的所有元素求和
fun sum [] = 0
| sum (x::xs) = x + sum xs
甚至创建一个长度函数(实际上类似于您的计数函数)
fun length [] = 0
| length (x::xs) = 1 + length xs
我鼓励你去阅读这些questions 和他们的答案,而不是重复很多已经提到的好东西。
更新
我还想向您展示如何以更好的方式格式化您的代码
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
如何格式化嵌套的 if 始终是我来自哪里的一场激烈争论。就我个人而言,我避免使用它们,而是使用用例,但我想您将来会倾向于使用它。
不过,我也发现您的计数功能有一个错误。当您测试您的第二个参数(在您的两个计数函数中)是否是带有null 的空列表时,您在参数的尾部执行此操作,如果参数实际上是空列表,则会失败
- null (tl []);
uncaught exception Empty
例如这个输入
- number_in_months ([(1,1,1)], [1]);
uncaught exception Empty
您在number_in_month 中的逻辑也是错误的,因为您正在测试datelist 的头部是否等于month,但是您对count 在任何一种情况下都使用整个datelist 而不是它的尾巴。这被视为下面不应返回 2 作为结果
- number_in_month([(1,1,1), (2,2,2), (3,3,3)], 1);
val it = 2 : int
这个错误是唯一使number_in_month 函数不抛出异常的原因。