SML:如何将列表列表化为子列表

SML:如何将列表列表化为子列表,sml,Sml,这个问题是我从学校里发现的 将一个列表划分为一个或多个子列表,使每个子列表包含按非减数(排序)顺序排列的整数 [3,5,1,8,9,2,1,0]返回[[3,5],[1,8,9],[2],[1],[0]] [1,2,3,4,5,6]返回[1,2,3,4,5,6]] [5,4,3,2,1]返回[5]、[4]、[3]、[2]、[1]] 以下代码工作: val Q1 = [ 3, 5, 1, 8, 9, 2, 1, 0 ] val A1 = foldl ( fn (x, a) =>

这个问题是我从学校里发现的

将一个列表划分为一个或多个子列表,使每个子列表包含按非减数(排序)顺序排列的整数

[3,5,1,8,9,2,1,0]返回[[3,5],[1,8,9],[2],[1],[0]]

[1,2,3,4,5,6]返回[1,2,3,4,5,6]]

[5,4,3,2,1]返回[5]、[4]、[3]、[2]、[1]]

以下代码工作:

val Q1 = [ 3, 5, 1, 8, 9, 2, 1, 0 ]

val A1 = foldl (
    fn (x, a) => 
        if x > hd (hd a) then (x::hd a)::tl a
        else [x]::a 
    ) [ [ hd Q1 ] ] (tl Q1)

val A1 = map rev (rev A1)
或者像这样:使用2个临时列表来收集

fun split l = let
    fun split' tmp subset =
        fn [] => []
        |  [x] => (x::tmp)::subset
        |  (a::(c as b::_)) =>
                if a < b then split' (a::tmp) subset c
                else split' [] ((a::tmp)::subset) c
    in (rev o map rev) (split' [] [] l) end
fun split l=let
有趣的分裂tmp子集=
fn[]=>[]
|[x]=>(x::tmp)::子集
|(a::(c为b::)=>
如果a
这个问题有这么多解决方案, 但我仍然想知道如何将其编码为模式匹配函数? 可能如下所示:

(不确定是否可能?

fun split[]=[]]
|拆分[x]=[x]]
|拆分[a,b]=如果a

这个问题真的让我很困惑。

假设这是家庭作业,我不想给出完整的答案,但这里有一些提示:

1) 在空基情况下,我认为您希望返回
[[]]
,而不是
[]
。您的规范没有解决这个问题,但是由于空列表是可以从空列表前面提取的最长的非减数整数列表,因此返回值应该是由空列表组成的列表。这有点类似于空集的powerset(所有子集的集合)是包含空集的集合,而不是空集本身。你如何定义这个特殊的案例并不重要,因为真正的基础案例是

2) 在
[x]
情况下,您确实需要返回
[[x]]
而不是
[x]
,因为您尝试编写的函数类型是
int list->int list

3) 在剩下的情况下,您可以编写如下模式

|    split (x::y::zs) = (* fill this in *)

然后测试是否
x谢谢!这不是家庭作业。请给我一个完整的密码。我不知道如何加入结果。谢谢。太完美了。在polyml中,它有一个警告:模式不是详尽的。接近val first::rest=split(y::zs)。如何删除该警告?我使用
val ret=split2(y::z)
,以及hd、tl来删除它。有什么想法吗?谢谢SML/NJ没有发出警告。显然,PolyML推断
split
返回一个int列表,并注意到
val first::rest=split(y::zs)
split()的输出不匹配
如果返回值是空列表——但是稍微考虑一下就足以让您相信输出不可能是空的,因为
split
从不返回空列表。编译器警告只是检查潜在问题。在这种特殊情况下,它可以被忽略——或者如果您觉得警告很烦人,可以使用
hd
tl
|    split (x::y::zs) = (* fill this in *)
fun split [] = [[]]
|   split [x] = [[x]]
|   split (x::y::zs) =
    let val first::rest = split (y::zs) in
        if x <= y then
            (x::first) :: rest
        else
            [x]::first::rest
    end;