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

如何实现不丢失头部的Haskell列表对半拆分函数?

问题分析与解决

你的代码在处理长度大于1的列表时,直接对xs(原列表去掉头部后的剩余部分)执行splitAt,但计算的half是xs长度的一半,相当于把原列表的第一个元素完全排除在拆分逻辑外,自然会丢失头部元素。

下面是两种修正方案:

方案一:简洁版实现

直接基于整个列表的长度计算拆分点,同时简化分支逻辑:

halve       :: [a] -> ([a],[a])
halve []    = ([],[])
halve [x]   = ([x],[])
halve xs    = splitAt (length xs `div` 2) xs

调用halve [1,2,3,4]时,length xs为4,div 2得到拆分点2,splitAt 2 [1,2,3,4]会直接返回([1,2],[3,4]),完全符合你的需求。

方案二:保留原分支结构的实现

如果想保留原有的(x:xs)分支写法,可以将头部元素x拼到拆分后的第一个列表中,同时调整拆分点:

halve       :: [a] -> ([a],[a])
halve []    = ([],[])
halve [x]   = ([x],[])
halve (x:xs) = (x : firstPart, secondPart)
    where totalLength = 1 + length xs
          half = totalLength `div` 2
          (firstPart, secondPart) = splitAt (half - 1) xs

这里先计算原列表的总长度,拆分点half取总长度的一半,再对xs拆分half-1个元素,最后把头部x加到第一个拆分结果的前面,同样能得到正确输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 11:27:27