SML列表迭代

And*_*lin 2 iteration date list sml

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

我有一个先前定义的number_in_month函数,它接受一个日期列表和一个月,并返回该月份的日期量.它已经过测试并且工作正常.我用它作为后一种功能的基础.我已经number_in_months多次追踪这个功能了,我似乎无法找出错误但是它根本没有得到正确的答案

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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

Jes*_*erg 7

如您所述,您只需使用上一个功能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)
Run Code Online (Sandbox Code Playgroud)

但是,当您使用模式匹配时,可以将其缩短并使其更具可读性

fun number_in_months (dates, []) = 0
  | number_in_months (dates, d::ds) =
      number_in_month(dates, d) + number_in_months(dates, ds)
Run Code Online (Sandbox Code Playgroud)

绝对没有理由创造一个count带有"状态"的功能.这似乎是你的命令性思维,在游戏中:)以这个简单的函数为例,它将对列表的所有元素求和

fun sum [] = 0
  | sum (x::xs) = x + sum xs
Run Code Online (Sandbox Code Playgroud)

甚至创建一个长度函数(实际上类似于你的计数函数)

fun length [] = 0
  | length (x::xs) = 1 + length xs
Run Code Online (Sandbox Code Playgroud)

我鼓励你去阅读这些问题及其答案,而不是重复已经多次提到的很多好东西.

更新

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

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
Run Code Online (Sandbox Code Playgroud)

如何格式嵌套如果我总是很讨论我来自哪里.我个人避免使用它们,而是使用案例,但我想你将来会依赖它.

但是我也发现了你的计数功能错误.当你测试你的第二个参数(在你的两个计数函数中)是否为空列表时null,你在参数的尾部进行测试,如果参数实际上是空列表,则会失败

- null (tl []);

uncaught exception Empty
Run Code Online (Sandbox Code Playgroud)

例如这个输入

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

uncaught exception Empty
Run Code Online (Sandbox Code Playgroud)

你的逻辑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
Run Code Online (Sandbox Code Playgroud)

这个错误是使number_in_month函数不会抛出异常的唯一因素.