如何在递归函数中使用if-then-else

时间:2017-03-29 00:07:07

标签: sml smlnj

我正在编写一个函数,它将获取列表列表并将其合并到已排序的列表对中。例如[[1],[9],[8],[7],[4],[5],[6]]将返回[[1,9],[7,8],[4,5] ],[6]。这是我第一次尝试SML。我一直收到这个错误:运算符和操作数不同意[过载冲突]。

    fun mergePass[] = []
    |   mergePass(x::[]) = x::[]
    |   mergePass(x::y::Z) = 
        if x<y
        then (x @ y)::mergePass(Z)
        else (y @ x)::mergePass(Z);

编辑:如果在[[1,9],[7,8],[4,5],[6]]上调用mergePass,我将需要它返回[[1,7,8,9], [4,5,6]。

此合并功能需要两个排序列表

   fun merge([],y) = y
   |   merge(x,[]) = x
   |   merge(a::x,b::y) =
   if a < b then a::merge(x,b::y)
   else b::merge(a::x,y);

1 个答案:

答案 0 :(得分:1)

你似乎相当接近。一些提示/评论:

1)在美学上,在一行中使用nil而在其他行中使用[]似乎很奇怪。使用全部nil或使用全部[]

2)由于输入是列表列表,在x::y::z中,标识符xy将是整数的列表,而不是单个整数。因此,x<y没有意义。您无法使用<比较整数列表。

3)您的问题描述强烈建议内部列表都是1个元素的列表。因此,您可以使用模式[x]::[y]::z来比较xy。在这种情况下,x@y可以替换为[x,y]

4)如果允许内部列表具有任意大小,那么您的代码需要进行重大修订,并且可能需要一个完整的排序函数来对连接内部列表对的结果进行排序。此外,在这种情况下,应该对一个内部列表中的单个列表进行排序。

5)您有拼写错误:mergeP不是mergePass

在编辑

如果每个子列表都已排序(并且整个函数的名称可能暗示了这一点),那么您需要一个名为eg的函数。 merge将获取两个排序列表并将它们组合成一个排序列表。如果这是一个类,并且您已经看到merge函数作为示例(可能在合并排序的讨论中) - 只需使用它。否则,在编写此函数之前,您必须自己编写。获得合并功能后,跳过比较xy的部分,而不是像以下一样简单:

| mergePass (xs::ys::zss) = (merge xs ys) :: mergePass zss

如果子列表未合并,那么您将需要一个完整的排序,在这种情况下,您将使用以下内容:

| mergePass (xs::ys::zss) = sort(xs @ ys) :: mergePass zss