2

我在完成这项任务时遇到了一些麻烦。这是教授要求的:

编写一个最旧的函数,它接受一个日期列表并计算一个 (int*int*int)选项。如果列表没有日期,则评估为 NONE,如果日期 d 是列表中最旧的日期,则评估为 SOME 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
4

1 回答 1

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)
于 2013-01-24T13:15:33.833 回答