我在这项任务中遇到了一些麻烦。这就是教授所要求的:
编写一个最旧的函数,该函数获取日期列表并评估为
(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
答案 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)