【发布时间】:2014-01-16 09:13:56
【问题描述】:
我目前正在学习 SML,我很难理解下面的代码
fun good_max (xs : int list) =
if null xs
then 0
else if null (tl xs)
then hd xs
else
(* for style, could also use a let-binding for (hd xs) *)
let val tl_ans = good_max(tl xs)
in
if hd xs > tl_ans
then hd xs
else tl_ans
end
hd xs 是 int 和 tl_ans 类型,我认为是 list 类型。
为什么这段代码有效?系统如何评估递归?
如果您可以使用 xs = [3, 4, 5] 向我展示它是如何工作的,那就太好了。
【问题讨论】:
-
` let val y = old_max(tl[3,4,5]) in max(hd[3,4,5], y) end let val y = (let val y' = old_max (tl(tl[3,4,5))) in max(hd(tl[3,4,5],y')) end) in max(hd[3,4,5],y) let val y = (let val y' = old_max([5]) in max(4,y') end) in max(3,y) end let val y = 5 in max (3,y) 5`
-
好的。我在尝试将代码放入评论框中时搞砸了。谢谢安德烈亚斯!我能够弄清楚您的工作原理并将其应用于我的代码。使用辅助函数使代码更优雅 :) 我的假设发生了错误,因为在评估函数之前我没有替换所有分支。递归确实是一个具有挑战性的话题。
-
FWIW,
max函数已作为Int.max存在于标准库中。此外,第三种情况的右侧显然可以简化为max(x, goodMax xs)——我没有这样做来演示let中的缩减是如何工作的。最后,我建议宁愿在空的情况下抛出异常,因为结果 0 并不完全正确。总而言之,您可以将函数用折叠表示为简单的fun goodMax [] = raise Empty | goodMax(x::xs) = List.foldl Int.max x xs。