Recursion 如何理解SML中的这种递归?
为什么hd日期成为最早的日期?我就是搞不懂这个过程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
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
分支,让tingd
beNONE
,因为只有一个元素的列表的tl
返回一个空列表isSome d
将为false,这就是为什么我们将返回SOME(hd日期)
——唯一的元素,根据定义,它是最古老的
else
分支,并将列表尾部最早的元素分配给d
(该元素有效,因为它包含n-1个项目)。现在有两种可能的情况:
a<代码>d早于列表的第一个元素。在这种情况下,d
将被返回,因为是一些d
并且更老(valOf d,hd dates)
将为真
b<代码>d不早于列表的第一个元素。因此,我们将返回列表的第一个元素SOME(hd日期)
在我看来,使用一个小的辅助函数和模式匹配的案例分析,这更容易理解。
(我的建议是熟悉模式和案例分析,避免使用条件和选择器函数。一次只对一件事进行推理要比记住整个逻辑和分解链容易得多。) 以这种方式重写代码可能会得到以下结果:
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)))
这与最早日期的定义非常相似:
- 如果没有日期,则没有最早的日期
- 如果只有一个日期,那就是最早的日期
- 如果至少有两个日期,则是第一个日期中最长的日期,其余日期中最长的日期
这不需要太多的归纳思考。你到底不明白什么?想想一个空的列表,一个有一个元素的列表,一个有两个元素的列表,等等会发生什么。谢谢你给我一个如此精确的答案!!!我最近在学习归纳法,我知道如何在数学中证明它,但当我要求在编程中证明时,我发现这真的很难。