You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell新手求助:如何定义列表的非平凡分割函数

问题分析

你的代码核心问题是递归时没有累积头部元素:处理(l:ls)时,你只生成了([l], ls)这个分割,然后直接拼接splits ls的结果,但splits ls返回的分割里,左半部分并没有把当前的l加进去,导致最终结果里每个元组的左半部分都是单个元素,而非逐步累积的子列表。

另外题目要求“非平凡分割”,通常指左右子列表都不为空,所以空列表的情况应该返回空列表,而非包含([],[])的平凡分割。

修正后的实现
splits :: [Int] -> [([Int],[Int])]
splits [] = []
splits (x:xs) = ([x], xs) : map (\(a,b) -> (x:a, b)) (splits xs)
代码解释
  • 递归基例:空列表没有非平凡分割,直接返回[]。
  • 递归步骤:
    1. 先生成当前列表的第一个非平凡分割:左半部分是[x],右半部分是剩余的xs。
    2. 递归处理剩余列表xs,得到xs的所有非平凡分割。
    3. 用map把每个递归得到的分割(a,b)转换为(x:a, b)——这一步就是把当前头部元素x累积到左半部分的前面,生成更长的左子列表。
测试结果

对于输入[1,2,3,4],运行结果为:

[([1],[2,3,4]), ([1,2],[3,4]), ([1,2,3],[4])]

完全符合非平凡分割的要求:每个元组的左右子列表都不为空,且覆盖了所有可能的分割方式。

额外扩展(通用类型)

如果想让函数支持任意类型的列表,而非仅[Int],可以修改类型签名:

splits :: [a] -> [([a], [a])]

这样函数可以处理[Char]、[Bool]等任意列表类型,实用性更强。

内容的提问来源于stack exchange,提问作者SixtyFever

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 19:50:26