2

我想知道,如何在列表中找到最旧的日期:

fun the_oldest_date(date_list: (int * int * int) list) = 
  let
    (*it might be useful*)
    fun older_date(date1: (int * int * int), date2: (int * int * int)) = 
      if #1 date1 < #1 date2 andalso
         #2 date1 < #2 date2 andalso
         #3 date1 < #3 date2
      then date1
      else date2
  in
    if null date_list
    then NONE
    else SOME older_date(hd date_list, the_oldest_date(tl date_list))
  end

我不想在这里使用任何库函数,只使用递归和标准 ML 工具。我得到了错误

Error: operator is not a function [tycon mismatch]
  operator: ((int * int * int) * (int * int * int) -> int * int * int) option
in expression:
  (SOME older_date) (hd date_list,the_oldest_date (tl date_list))
/usr/lib/smlnj/bin/sml: Fatal error -- Uncaught exception Error with 0
4

5 回答 5

2

亚历克斯,

您的 old_date 功能无法正常工作。您没有考虑具有相同年份和/或月份的两个日期(即 (1,1,1) 和 (1,1,2))。最后这个函数不应该返回bool一个(int * int * int).

找到最大值有点棘手,因此您应该尝试找到列表尾部的最大值,然后将其与头部进行比较。

我希望这有帮助。我的代码是:

fun the_oldest_date(date_list : (int * int * int) list) : (int * int * int) option = 
    let 
        fun older_date(date1:(int * int * int) , date2:(int * int * int)) : bool =
            if #1 date1 < #1 date2 
            then true
            else if #1 date1 = #1 date2
                 then if #2 date1 < #2 date2 
                      then true
                      else if #2 date1 = #2 date2
                           then if #3 date1 < #3 date2 
                                then true
                                else false
                           else false
                 else false  
     in        
        if null date_list 
        then NONE
        else
            let
                val prevMax = the_oldest_date(tl date_list)
            in
                if prevMax = NONE
                then SOME(hd date_list)
                else if older_date(hd date_list, valOf prevMax)
                     then SOME(hd date_list)
                     else prevMax
            end
    end
于 2013-10-14T11:56:58.677 回答
1

有三个问题。

首先,你忘记了括号

SOME older_date(hd date_list, the_oldest_date(tl date_list))

正如 SML 告诉你的那样,这被解释为

(SOME older_date) (hd date_list, the_oldest_date(tl date_list))

并且SOME older_date不是函数。

由于older_date有类型

(int * int * int) * (int * int * int) -> int * int * int 

SOME older_date有类型

((int * int * int) * (int * int * int) -> int * int * int) option

你应该做到

SOME (older_date(hd date_list, the_oldest_date(tl date_list)))

(函数应用程序关联到左侧,所以a b c表示(a b) c而不是 a (b c)

除了这也不起作用,因为第二个问题。

第二个问题是the_oldest_date返回一个int * int * int option, 而older_date期望一个int * int * int(您可能需要考虑更具体的数据类型 - 在这里无法分辨日期的哪个部分)。
在将结果传递给比较函数之前,您需要检查结果the_oldest_date (tl date_list)以查看它是否确实返回了某些内容。

第三个问题是您的日期比较有点时髦。
据我所知,您声称没有任何日期于 2014 年 1 月 1 日。
我对此表示怀疑。

于 2013-10-14T14:22:17.077 回答
0

sml 抱怨是因为您使用的是选项类型。'a option = NONE | SOME of 'a即参数(SOME older_date)...应该是一个单一的元素,它应该是你最早的日期。

于 2013-10-13T12:56:41.927 回答
0

好的。第一件事第一,删除最后一个andalso里面older_date

于 2013-10-13T22:33:59.583 回答
0

我会将每个日期转换为一个纪元,然后比较整数。就像是

epoch = (#1 date-1) * 365 + daysBeforeMonth(#2 date) + (#3 date)
于 2013-10-14T08:44:14.560 回答