Haskell将列表改为NonEmpty后,如何实现groupBy+take+concat逻辑?
解决NonEmpty concat的问题
你可以利用NonEmpty的<>运算符(Semigroup实例)来替代concat的功能,结合NonEmpty原生的groupBy就能实现目标函数,全程用NonEmpty原生操作,避免空列表判断。
实现思路
- 用
Data.List.NonEmpty.groupBy对输入的NonEmpty a分组,得到NonEmpty (NonEmpty a)(每个分组都是非空的)。 - 根据传入的Int值筛选分组:
- 若n≤0,只保留第一个分组(保证结果非空,符合返回类型要求)
- 若n≥1,保留第一个分组加上后续n-1个分组
- 用
<>把选中的所有分组连接成一个NonEmpty a
代码示例
先导入必要模块:
import Data.List.NonEmpty (NonEmpty(..), groupBy, (<>))
实现myTake'(如果你的someFunc是固定的,直接替换掉groupFunc即可):
myTake' :: Int -> (a -> a -> Bool) -> NonEmpty a -> NonEmpty a myTake' n groupFunc xs = foldl (<>) firstGroup selectedRestGroups where allGroups = groupBy groupFunc xs (firstGroup :| restGroups) = allGroups selectedRestGroups = take (max 0 (n - 1)) restGroups
补充说明
这种方式全程不需要在列表和NonEmpty之间来回转换,也不用处理空列表的边界情况,完全贴合你用NonEmpty简化代码的重构目标。当n≤0时,函数自动返回第一个分组,确保结果始终是非空的,满足NonEmpty a的类型约束。
内容的提问来源于stack exchange,提问作者composerMike
相关产品推荐
相关产品推荐

