如何从SML中的日期列表中获取最早的日期?

时间:2013-01-24 12:46:23

标签: sml

我在这项任务中遇到了一些麻烦。这就是教授所要求的:

  

编写一个最旧的函数,该函数获取日期列表并评估为   (int*int*int)选项。如果列表没有日期,则评估为NONE   如果日期d是列表中最早的日期,则为某些日期。

我知道如何创建函数并对如何使用日期列表有所了解,但我不知道如何“存储”最旧的值以将其与日期列表的尾部进行比较。这是我提交的内容(它不起作用,它总是检索第一个日期,但我真的很想知道答案)

fun oldest (datelist : (int * int * int) list) =
    if null datelist
    then NONE
    else if null (tl datelist) then
    SOME (hd datelist)
    else let val date = if is_older (hd datelist, hd (tl datelist)) then SOME (hd datelist) else SOME (hd (tl datelist))
     in oldest(tl datelist)
     end

1 个答案:

答案 0 :(得分:5)

在递归调用中保持值的一种方法是在参数中传递它。由于您无法更改原始函数,因此最常用的解决方案是使用辅助函数来获取此额外参数,以及其他可能的参数。
这样的辅助函数可以取列表的头部并将其与额外的参数进行比较,使用列表尾部的递归调用中最旧的两个参数。然后当列表为空时,你只需返回这个额外的参数,因为它必须是最旧的。

fun oldestOfTwo (d1, d2) = (* return the oldest/minimum of the two dates *)

fun oldest [] = NONE
  | oldest (d::ds) =
    let
      fun oldest' max [] = SOME max
        | oldest' max (d::ds) =
          oldest (oldestOfTwo (max, d2)) ds
    in
      oldest' d ds
    end

另一个解决方案可能是取出列表中的两个第一个元素,放回两个中最老的元素,因此在每个递归调用中删除列表中的一个元素,并且在某些时候只会有一个元素列表,必须是最早的。

fun oldest [] = NONE
  | oldest [d] = SOME d
  | oldest (d1 :: d2 :: ds) = oldest (oldestOfTwo (d1, d2) :: ds)