从日期列表中获取min元素(运算符不是函数[tycon mismatch])

时间:2013-10-13 07:12:30

标签: sml ml

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

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

5 个答案:

答案 0 :(得分: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

答案 1 :(得分: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(您可能需要考虑更具体的数据类型 - 它&#39;}我不可能知道这个日期的哪一部分在这里。) 您需要检查the_oldest_date (tl date_list)的结果,看看它是否在将其传递给比较函数之前实际返回了某些内容。

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

确定。首先,删除andalso内的最后一个older_date

答案 4 :(得分:0)

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

这样的东西
epoch = (#1 date-1) * 365 + daysBeforeMonth(#2 date) + (#3 date)