首先,当列表非常随机时,排序不起作用,例如, f [2,3,4,1,2,4,6,0,6,7]
其次,要回答你的问题,以这种特殊的功能是如何工作的, 你可以用以下print
添加到您的代码很容易想象它:
fun f ([x]) = [x]
| f(x :: ls) = (print((Int.toString (x))^"\n");
let
val (y :: ys) = f ls
val x_str = Int.toString (x)
val y_str = Int.toString (y)
val ys_str = concat (map Int.toString ys);
val y_gt_x = if y > x then " ---> this one applies " else ""
val x_gt_y = if x >= y then " ---> this one applies " else ""
in
(print ("if "^y_str^" > "^x_str^
"\n then "^x_str^" :: "^y_str^ys_str^y_gt_x^
"\n else "^y_str^" :: "^x_str^ys_str^x_gt_y^"\n");
if y > x then x :: y :: ys
else
y :: x :: ys)
end)
这对于对上述无序列表输出以下内容:
- f [2,3,4,1,2,4,6,0,6,7];
2
3
4
1
2
4
6
0
6
if 7 > 6
then 6 :: 7 ---> this one applies
else 7 :: 6
if 6 > 0
then 0 :: 67 ---> this one applies
else 6 :: 07
if 0 > 6
then 6 :: 067
else 0 :: 667 ---> this one applies
if 0 > 4
then 4 :: 0667
else 0 :: 4667 ---> this one applies
if 0 > 2
then 2 :: 04667
else 0 :: 24667 ---> this one applies
if 0 > 1
then 1 :: 024667
else 0 :: 124667 ---> this one applies
if 0 > 4
then 4 :: 0124667
else 0 :: 4124667 ---> this one applies
if 0 > 3
then 3 :: 04124667
else 0 :: 34124667 ---> this one applies
if 0 > 2
then 2 :: 034124667
else 0 :: 234124667 ---> this one applies
val it = [0,2,3,4,1,2,4,6,6,7] : int list
-
正如你所看到的,功能f
递归调用自身在let
绑定区段。 (检查代码: let val (y :: ys) = f ls
,你可以看到,f ls
是函数f
的递归调用,所以你的y :: ys
分析作为in
体内的递归调用是不正确的,这仅仅是在前面加上的操作元素y
至列表ys
)
in
主体不会被评估,除非一直列在列表的末尾。因此,in
正文将首先评估列表的最后两个元素,例如7 > 6
并相应地增加列表ys
。
第三,回答点数一个,为什么排序功能f
不能正常工作,是因为它不断加入新的元素,ys
如果没有新的元素放入顺序ys
相对于其余看到元素。是的,列表ys
的第一个元素与要添加的新元素进行比较,因此两个中最大的元素将首先添加到ys
的剩余部分,但这不能保证关于第二个元素的正确放置第三等元素ys
。
感谢您花时间设置和解释!所以我很清楚1)递归调用然后首先运行首先将列表拆分为用于比较的元素? 2)那么随着它的增长,ys就是新的列表了吗? – cpd1
或多或少,更确切地说:递归调用将列表中的每个元素解除绑定到堆中并接近列表末尾,堆被回溯并且每个单独的元素相应地被挖掘并进行比较,然后将这些元素插入到ys中。我建议你使用我提供的简单输入和更复杂输入的代码来玩,并理解为什么只输出第一个数字,然后只进行比较。 –
我会感谢。这非常有用,所以非常感谢您为我整理这些内容。我一直在努力了解这是如何工作的,但这应该有所帮助 – cpd1