Recursion 如何理解SML中的这种递归?

Recursion 如何理解SML中的这种递归?,recursion,sml,Recursion,Sml,为什么hd日期成为最早的日期?我就是搞不懂这个过程 fun oldest(dates : (int * int * int) list) = if null dates then NONE else let val d = oldest(tl dates) in if isSome d andalso is_older(valOf d, hd dates) then

为什么hd日期成为最早的日期?我就是搞不懂这个过程

fun oldest(dates : (int * int * int) list) = 
    if null dates
    then NONE
    else
        let
            val d = oldest(tl dates)
        in
            if isSome d andalso is_older(valOf d, hd dates) 
            then d
            else SOME(hd dates) 
        end

你可以通过归纳法证明这一点:

  • 如果列表为空,
    最早的
    将返回

  • 如果列表包含一个元素,我们将进入
    else
    分支,
    ting
    d
    be
    NONE
    ,因为只有一个元素的列表的
    tl
    返回一个空列表
    isSome d
    将为false,这就是为什么我们将返回
    SOME(hd日期)
    ——唯一的元素,根据定义,它是最古老的

  • 假设该函数适用于n-1个项目的列表,让我们看看当列表有n个项目时会发生什么:我们将进入
    else
    分支,并将列表尾部最早的元素分配给
    d
    (该元素有效,因为它包含n-1个项目)。现在有两种可能的情况:

    a<代码>d
    早于列表的第一个元素。在这种情况下,
    d
    将被返回,因为
    是一些d
    并且
    更老(valOf d,hd dates)
    将为真

    b<代码>d
    不早于列表的第一个元素。因此,我们将返回列表的第一个元素
    SOME(hd日期)

  • 我们已经证明,如果它适用于n-1,它适用于n个元素,并且我们已经证明它适用于n=0和n=1(从技术上讲,我们可以跳过步骤2)。因此,它适用于任何大小的列表


  • 在我看来,使用一个小的辅助函数和模式匹配的案例分析,这更容易理解。
    (我的建议是熟悉模式和案例分析,避免使用条件和选择器函数。一次只对一件事进行推理要比记住整个逻辑和分解链容易得多。)

    以这种方式重写代码可能会得到以下结果:

    fun oldest_of (d, d') = if is_older (d, d') then d else d'
    
    fun oldest [] = NONE
      | oldest (d::ds) = case oldest ds of
                            NONE => SOME d
                          | SOME d' => SOME (oldest_of (d, d'))
    
    就是

    • 如果列表为空,则不存在最早的日期
    • 否则,在输入的尾部查找最早的日期;
      • 如果没有,则输入的第一个元素必须是最早的元素
      • 否则,选择其中最早的元素和输入的第一个元素
    现在(希望)很明显,递归中的
    NONE
    情况只有在尾部
    ds
    为空时才会出现,也就是说,如果输入只有一个元素。
    让我们将其提升到自己的案例中:

    fun oldest [] = NONE
      | oldest [d] = SOME d
      | oldest (d::ds) =  SOME (oldest_of (d, valOf (oldest ds)))
    
    这与最早日期的定义非常相似:

    • 如果没有日期,则没有最早的日期
    • 如果只有一个日期,那就是最早的日期
    • 如果至少有两个日期,则是第一个日期中最长的日期,其余日期中最长的日期

    这不需要太多的归纳思考。

    你到底不明白什么?想想一个空的列表,一个有一个元素的列表,一个有两个元素的列表,等等会发生什么。谢谢你给我一个如此精确的答案!!!我最近在学习归纳法,我知道如何在数学中证明它,但当我要求在编程中证明时,我发现这真的很难。