List 每月练习次数(SML列表迭代)

List 每月练习次数(SML列表迭代),list,date,iteration,sml,List,Date,Iteration,Sml,我需要一个日期列表和一个月列表,并获得列出的任何月份的日期总数。因此返回一个整数 我有一个以前定义的number\u in\u month函数,它接受一个 日期和一个月,并返回该月份的日期数 一个月。它已经过测试,工作正常。我以此为基础 后一种功能。我在几个月内跟踪了number\u函数 《时代周刊》和《我》似乎无法找出问题所在,但它根本没有给出正确的答案 fun number_in_month (datelist : (int*int*int)list, month : int) = l

我需要一个日期列表和一个月列表,并获得列出的任何月份的日期总数。因此返回一个整数

我有一个以前定义的
number\u in\u month
函数,它接受一个 日期和一个月,并返回该月份的日期数 一个月。它已经过测试,工作正常。我以此为基础 后一种功能。我在几个月内跟踪了
number\u
函数 《时代周刊》和《我》似乎无法找出问题所在,但它根本没有给出正确的答案

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

如前所述,您只需使用上一个函数
number\u in\u month
。记住
number\u in_month
获取日期列表和单个月份,并返回日期列表中匹配的月份数。因此,创建
number\u in_month
,只需为新的月份列表中的每个元素调用
number\u 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
甚至创建一个长度函数(实际上与count函数类似)

我鼓励你去读这些书和他们的答案,而不是重复很多已经提到过很多次的好东西

更新

我还想向您展示如何以更好的方式格式化代码

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的格式一直是一个很大的争论。就我个人而言,我避免使用它们,而是使用用例,但我想你将来会在这方面有所收获

但是我也发现了计数函数中的一个错误。当您测试第二个参数(在两个count函数中)是否为带有
null
的空列表时,您可以在参数的尾部进行测试,如果该参数实际上是空列表,则测试将失败

- null (tl []);

uncaught exception Empty
例如,这个输入

- number_in_months ([(1,1,1)], [1]);

uncaught exception Empty
另外,您在
number\u in_month
中的逻辑是错误的,因为您正在测试
datelist
的头是否等于
month
,但是您的to
count
在这两种情况下都使用整个
datelist
。这是因为下面的结果不应返回2

- number_in_month([(1,1,1), (2,2,2), (3,3,3)], 1);
val it = 2 : int

此错误是唯一导致
number\u in\u month
函数未引发异常的原因。

代码的问题是,如果最后日期与月份匹配,则无法计算最后日期。这段代码运行良好

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 
              if #2(hd datelist) <> month
                      then x
                     else x+1
         else if #2(hd datelist) = month
            then count (x+1, tl datelist)
            else count (x, tl datelist)
    in
          count (0, datelist)
    end
fun number(日期列表:(int*int*int)列表,月份:int)=
让
乐趣计数(x:int,日期列表:(int*int*int)列表)=
如果为空(tl日期列表)
然后
如果#2(hd日期列表)月
然后x
其他x+1
如果#2(hd日期列表)=月份
然后计数(x+1,tl日期列表)
else计数(x,tl日期列表)
在里面
计数(0,日期列表)
结束

哇,我真不敢相信事情会这么简单。非常感谢,muchI已经更新了答案,并提供了一些关于如何去掉计数函数的示例,以及一些建议您应该去阅读的问题/答案。在尝试给出一个关于如何缩进的示例时,在代码中发现了一些错误。然而,如果你发现这是你问题的答案,你可能不会接受。你太棒了。谢谢你的仔细检查response@AndrewMcLaughlin,你可能会发现人们将来更愿意回答你的问题。如果你接受答案,你会发现最好的答案。
- number_in_month([(1,1,1), (2,2,2), (3,3,3)], 1);
val it = 2 : int
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 
              if #2(hd datelist) <> month
                      then x
                     else x+1
         else if #2(hd datelist) = month
            then count (x+1, tl datelist)
            else count (x, tl datelist)
    in
          count (0, datelist)
    end