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

Haskell新手求助:实现scanD函数完成嵌套列表展开需求

完成scanD函数的解决方案

首先,先确认你的expand函数逻辑是对的——它接收一个形如[值, 重复次数]的列表,返回该值重复对应次数的列表,比如expand [7,3]会生成[7,7,7],完全符合需求👍。

接下来要实现的scanD函数,核心就是遍历嵌套列表中的每一个子列表,对每个子列表调用expand展开,然后把所有展开后的列表拼接在一起。这里用递归的方式就能轻松实现:

main= print(scanD [[7,3],[8,5],[7,2]])

expanding :: Int -> [Int] -> [Int]
expanding y (n:ns) | (n>0) = y:expanding y (n-1:ns) | otherwise = []

expand :: [Int] -> [Int]
expand (x:xs) = expanding x xs

scanD :: [[Int]] -> [Int]
scanD [] = []  -- 空的嵌套列表返回空列表,作为递归终止条件
scanD (sub:rest) = expand sub ++ scanD rest  -- 展开第一个子列表,拼接剩余子列表的展开结果

逻辑解释

  1. 空列表情况:当scanD接收空的嵌套列表时,直接返回空列表,结束递归。
  2. 非空列表情况:
    • 取出第一个子列表sub,用expand把它展开成重复值的列表;
    • 递归调用scanD处理剩下的子列表rest,得到它们的展开结果;
    • 用++把这两部分结果拼接起来,就得到了最终的展开列表。

测试你的例子,scanD [[7,3],[8,5],[7,2]]会依次处理:

  • expand [7,3] → [7,7,7]
  • expand [8,5] → [8,8,8,8,8]
  • expand [7,2] → [7,7]
    拼接后就是[7,7,7,8,8,8,8,8,7,7],完全符合你的需求。

更简洁的写法

如果你熟悉Haskell的高阶函数,还可以用concatMap来简化scanD的实现,一行就能搞定:

scanD :: [[Int]] -> [Int]
scanD = concatMap expand

concatMap会自动遍历列表中的每个元素,应用expand函数,然后把所有结果拼接成一个列表,效果和递归写法完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:31:12