如何在sml中重复递归调用另一个函数?

How to recursively call another function repeatedly in sml?

I have a function called mergeP:

fun mergeP(nil) = nil
| mergeP(x::[]) = x::[]
| mergeP(x::y::zs) = (x @ y)::mergeP(zs);

If mergeP is called like: mergeP([[1],[2],[3],[4]]) it will return [[1,2],[3,4]]. I want to create a function called mergeS that is recursive that repeatedly calls mergeP till the sublist equals just one list. So if mergeS were called like: mergeS([[1],[2],[3],[4]]) it would repeatedly call mergeP till it equals: [1,2,3,4]. Here is my try:

- fun mergeS(nil) = nil
= |mergeS(xs) = mergeS(mergeP(xs));

But this gives me the error:

stdIn:6.1-6.26 Warning: type vars not generalized because of
   value restriction are instantiated to dummy types (X1,X2,...)
val it = [] : ?.X1 list

I believe I got it to work:

fun mergeS(nil) = nil
| mergeS([xs]) = xs
| mergeS(xs) = mergeS(mergeP(xs));

尽管可以跳过 mergeP 并直接定义 mergeS,但您的解决方案效果很好:

fun mergeS [] = []
|   mergeS ([]::xss) = mergeS xss
|   mergeS ((x::xs)::xss) = x :: mergeS (xs::xss);

在第三行中,函数递归地提取第一个内部列表中的元素并将它们添加到最终结果中。当第一个列表中没有其他内容可以提取时,您就完成了它,第二行将其丢弃并继续处理其余的内部列表。当没有更多的内部列表要处理时,您将在第 1 行中找到基本情况并完成。

您正在调用的这个函数 mergeS 更习惯地称为 flatten,因为它 "flattens" 将列表的列表合并为一个列表。这使单个级别变平。您还可以编写一个函数来展平例如两个级别(列表的列表到单个列表的列表),但是,正如@molbdnilo 在评论中指出的那样,在 SML 中不可能编写可以将嵌套列表展平为任意嵌套级别的函数。你不能写一个函数,例如将与 [[[1,2]],[[3],[4]]] 以及 [[1],[2],[3],[4]] 一起工作,因为 SML 的类型系统没有对应于任意嵌套列表的类型构造函数。