P22 - 生成整数范围
Create a list containing all integers within a given range
官方模块:
Problems.P22核心函数:range
← P21 在指定位置插入元素 | P23 从列表随机选 N 个元素 →
题目描述
生成从 from 到 to(两端包含)的所有整数组成的列表。如果 from > to,返回空列表。
函数签名
1range :: Int -> Int -> [Int]
实现
方法一:enumFromTo
1range :: Int -> Int -> [Int]
2range from to = [from .. to]
Haskell 内置的 Enum 语法糖,编译器会优化为 enumFromTo。最简洁,零样板代码。
注意:
[1..5]得到[1,2,3,4,5],[5..1]得到[](而不是逆序列表)。如果要降序范围,需要用[5,4..1]或range 1 5 |> reverse。
方法二:iterate + takeWhile
1range :: Int -> Int -> [a]
2range from to = takeWhile (<= to) (iterate (+ 1) from)
iterate (+ 1) from 生成 [from, from+1, from+2, ...] 的无限列表,takeWhile (<= to) 在超过终点时截断。当 from > to 时 takeWhile 首个元素就不满足条件,直接返回 []。
方法三:显式递归
1range :: Int -> Int -> [Int]
2range from to
3 | from > to = []
4 | otherwise = from : range (from + 1) to
不需要任何库函数,纯递归。加深了对列表构造的理解,但编译器不会像 enumFromTo 那样做融合优化。
方法对比
| 方法 | 行数 | 惰性 | 性能 |
|---|---|---|---|
| enumFromTo | 1 | ✅ 惰性列表 | GHC 会做 stream fusion |
| iterate | 1 | ✅ 惰性 | iterate + takeWhile 组合,略慢 |
| 显式递归 | 4 | ✅ 惰性 | 无优化,大范围略慢 |
测试
1>>> range 4 9
2[4,5,6,7,8,9]
3>>> range (-2) 2
4[-2,-1,0,1,2]
5>>> range 3 2
6[]