列表函数 #
一、访问函数 #
1.1 首尾元素 #
haskell
-- head:获取第一个元素
head [1, 2, 3, 4, 5] -- 1
head "hello" -- 'h'
-- last:获取最后一个元素
last [1, 2, 3, 4, 5] -- 5
last "hello" -- 'o'
-- 注意:对空列表会报错
-- head [] -- 错误!
1.2 首尾之外 #
haskell
-- tail:除第一个元素外的所有元素
tail [1, 2, 3, 4, 5] -- [2, 3, 4, 5]
tail "hello" -- "ello"
-- init:除最后一个元素外的所有元素
init [1, 2, 3, 4, 5] -- [1, 2, 3, 4]
init "hello" -- "hell"
-- 注意:对空列表会报错
-- tail [] -- 错误!
1.3 安全访问 #
haskell
-- 自定义安全版本
safeHead :: [a] -> Maybe a
safeHead [] = Nothing
safeHead (x:_) = Just x
safeTail :: [a] -> Maybe [a]
safeTail [] = Nothing
safeTail (_:xs) = Just xs
safeLast :: [a] -> Maybe a
safeLast [] = Nothing
safeLast [x] = Just x
safeLast (_:xs) = safeLast xs
safeInit :: [a] -> Maybe [a]
safeInit [] = Nothing
safeInit [x] = Just []
safeInit (x:xs) = (x:) <$> safeInit xs
1.4 索引访问 #
haskell
-- !! 运算符:索引访问(从0开始)
[1, 2, 3, 4, 5] !! 0 -- 1
[1, 2, 3, 4, 5] !! 2 -- 3
"hello" !! 1 -- 'e'
-- 安全索引
safeIndex :: [a] -> Int -> Maybe a
safeIndex xs n
| n < 0 || n >= length xs = Nothing
| otherwise = Just (xs !! n)
二、长度与判断 #
2.1 长度函数 #
haskell
-- length:获取长度
length [1, 2, 3, 4, 5] -- 5
length "hello" -- 5
length [] -- 0
-- null:判断是否为空
null [] -- True
null [1, 2] -- False
null "" -- True
2.2 存在性判断 #
haskell
-- elem:判断元素是否存在
elem 3 [1, 2, 3, 4, 5] -- True
elem 6 [1, 2, 3, 4, 5] -- False
'a' `elem` "hello" -- True
-- notElem:判断元素是否不存在
notElem 3 [1, 2, 3, 4, 5] -- False
notElem 6 [1, 2, 3, 4, 5] -- True
2.3 条件判断 #
haskell
-- all:所有元素满足条件
all even [2, 4, 6, 8] -- True
all even [2, 3, 4, 5] -- False
all (> 0) [1, 2, 3] -- True
-- any:任一元素满足条件
any even [1, 3, 5, 6] -- True
any even [1, 3, 5] -- False
any (< 0) [1, 2, 3] -- False
-- and:布尔列表全部为True
and [True, True, True] -- True
and [True, False, True] -- False
-- or:布尔列表任一为True
or [False, True, False] -- True
or [False, False, False] -- False
三、取与舍 #
3.1 固定数量 #
haskell
-- take:取前n个元素
take 3 [1, 2, 3, 4, 5] -- [1, 2, 3]
take 10 [1, 2, 3] -- [1, 2, 3] -- 不会越界
take 0 [1, 2, 3] -- []
take (-1) [1, 2, 3] -- []
-- drop:丢弃前n个元素
drop 3 [1, 2, 3, 4, 5] -- [4, 5]
drop 10 [1, 2, 3] -- []
drop 0 [1, 2, 3] -- [1, 2, 3]
-- splitAt:在指定位置分割
splitAt 3 [1, 2, 3, 4, 5] -- ([1, 2, 3], [4, 5])
splitAt 0 [1, 2, 3] -- ([], [1, 2, 3])
splitAt 10 [1, 2, 3] -- ([1, 2, 3], [])
3.2 条件取舍 #
haskell
-- takeWhile:取满足条件的元素
takeWhile (< 5) [1..10] -- [1, 2, 3, 4]
takeWhile even [2, 4, 6, 7, 8] -- [2, 4, 6]
takeWhile (/= ' ') "hello world" -- "hello"
-- dropWhile:丢弃满足条件的元素
dropWhile (< 5) [1..10] -- [5, 6, 7, 8, 9, 10]
dropWhile even [2, 4, 6, 7, 8] -- [7, 8]
-- span:分割为满足和不满足两部分
span (< 5) [1..10] -- ([1, 2, 3, 4], [5, 6, 7, 8, 9, 10])
span even [2, 4, 6, 7, 8] -- ([2, 4, 6], [7, 8])
-- break:span的否定
break (> 5) [1..10] -- ([1, 2, 3, 4, 5], [6, 7, 8, 9, 10])
break even [1, 3, 5, 6, 7] -- ([1, 3, 5], [6, 7])
3.3 分区 #
haskell
-- partition:按条件分为两部分
partition even [1..10] -- ([2, 4, 6, 8, 10], [1, 3, 5, 7, 9])
partition (> 5) [1..10] -- ([6, 7, 8, 9, 10], [1, 2, 3, 4, 5])
四、转换函数 #
4.1 反转 #
haskell
-- reverse:反转列表
reverse [1, 2, 3, 4, 5] -- [5, 4, 3, 2, 1]
reverse "hello" -- "olleh"
reverse [] -- []
4.2 过滤 #
haskell
-- filter:过滤满足条件的元素
filter even [1..10] -- [2, 4, 6, 8, 10]
filter (> 5) [1..10] -- [6, 7, 8, 9, 10]
filter isLetter "hello123" -- "hello"
4.3 映射 #
haskell
-- map:对每个元素应用函数
map (*2) [1, 2, 3, 4, 5] -- [2, 4, 6, 8, 10]
map show [1, 2, 3] -- ["1", "2", "3"]
map length ["hello", "world"] -- [5, 5]
-- map与组合
map (show . (*2)) [1, 2, 3] -- ["2", "4", "6"]
五、折叠函数 #
5.1 foldr #
haskell
-- foldr:右折叠
foldr (+) 0 [1, 2, 3, 4, 5] -- 15
foldr (*) 1 [1, 2, 3, 4] -- 24
foldr (:) [] [1, 2, 3] -- [1, 2, 3]
-- 计算过程
-- foldr (+) 0 [1, 2, 3]
-- = 1 + (2 + (3 + 0))
-- = 6
5.2 foldl #
haskell
-- foldl:左折叠
foldl (+) 0 [1, 2, 3, 4, 5] -- 15
foldl (*) 1 [1, 2, 3, 4] -- 24
foldl (flip (:)) [] [1, 2, 3] -- [3, 2, 1]
-- 计算过程
-- foldl (+) 0 [1, 2, 3]
-- = ((0 + 1) + 2) + 3
-- = 6
5.3 fold应用 #
haskell
-- 求和
sum' :: Num a => [a] -> a
sum' = foldl (+) 0
-- 求积
product' :: Num a => [a] -> a
product' = foldl (*) 1
-- 长度
length' :: [a] -> Int
length' = foldl (\acc _ -> acc + 1) 0
-- 拼接
concat' :: [[a]] -> [a]
concat' = foldr (++) []
-- 判断所有
all' :: (a -> Bool) -> [a] -> Bool
all' p = foldl (\acc x -> acc && p x) True
5.4 scan #
haskell
-- scanl:类似foldl但保留中间结果
scanl (+) 0 [1, 2, 3, 4] -- [0, 1, 3, 6, 10]
scanl (*) 1 [1, 2, 3, 4] -- [1, 1, 2, 6, 24]
-- scanr:类似foldr但保留中间结果
scanr (+) 0 [1, 2, 3, 4] -- [10, 9, 7, 4, 0]
六、组合函数 #
6.1 zip系列 #
haskell
-- zip:配对两个列表
zip [1, 2, 3] ['a', 'b', 'c'] -- [(1, 'a'), (2, 'b'), (3, 'c')]
zip [1, 2, 3] ['a', 'b'] -- [(1, 'a'), (2, 'b')]
-- zipWith:配对并应用函数
zipWith (+) [1, 2, 3] [4, 5, 6] -- [5, 7, 9]
zipWith (*) [1, 2, 3] [4, 5, 6] -- [4, 10, 18]
zipWith (,) [1, 2, 3] ['a', 'b', 'c'] -- [(1, 'a'), (2, 'b'), (3, 'c')]
-- zip3:三个列表配对
zip3 [1, 2, 3] ['a', 'b', 'c'] [True, False, True]
-- [(1, 'a', True), (2, 'b', False), (3, 'c', True)]
6.2 unzip系列 #
haskell
-- unzip:解配对
unzip [(1, 'a'), (2, 'b'), (3, 'c')] -- ([1, 2, 3], "abc")
-- unzip3:解三个配对
unzip3 [(1, 'a', True), (2, 'b', False)]
-- ([1, 2], "ab", [True, False])
6.3 concat系列 #
haskell
-- concat:拼接列表的列表
concat [[1, 2], [3, 4], [5, 6]] -- [1, 2, 3, 4, 5, 6]
-- concatMap:映射后拼接
concatMap show [1, 2, 3] -- "123"
-- 等价于
concatMap' f xs = concat (map f xs)
七、搜索函数 #
7.1 查找元素 #
haskell
import Data.List
-- find:查找满足条件的元素
find (> 3) [1, 2, 3, 4, 5] -- Just 4
find (> 5) [1, 2, 3] -- Nothing
-- filter:查找所有满足条件的元素
filter (> 3) [1, 2, 3, 4, 5] -- [4, 5]
7.2 查找位置 #
haskell
import Data.List
-- elemIndex:元素位置
elemIndex 3 [1, 2, 3, 4, 5] -- Just 2
elemIndex 6 [1, 2, 3] -- Nothing
-- elemIndices:所有位置
elemIndices 'a' "banana" -- [1, 3, 5]
-- findIndex:满足条件的位置
findIndex (> 3) [1, 2, 3, 4, 5] -- Just 3
-- findIndices:满足条件的所有位置
findIndices even [1, 2, 3, 4, 5, 6] -- [1, 3, 5]
7.3 关联列表 #
haskell
-- lookup:在关联列表中查找
lookup 2 [(1, "one"), (2, "two"), (3, "three")] -- Just "two"
lookup 4 [(1, "one"), (2, "two")] -- Nothing
八、排序函数 #
8.1 基本排序 #
haskell
import Data.List
-- sort:排序
sort [3, 1, 4, 1, 5, 9, 2, 6] -- [1, 1, 2, 3, 4, 5, 6, 9]
-- sort字符串
sort "hello" -- "ehllo"
8.2 自定义排序 #
haskell
import Data.List
-- sortBy:自定义比较
sortBy (flip compare) [1, 2, 3] -- [3, 2, 1] -- 降序
-- 按长度排序
sortBy (compare `on` length) ["abc", "de", "fghij"]
-- ["de", "abc", "fghij"]
-- 按元组元素排序
sortBy (compare `on` fst) [(3, 'a'), (1, 'b'), (2, 'c')]
-- [(1, 'b'), (2, 'c'), (3, 'a')]
8.3 分组 #
haskell
import Data.List
-- group:分组相邻相同元素
group [1, 1, 2, 2, 2, 3, 1, 1]
-- [[1, 1], [2, 2, 2], [3], [1, 1]]
-- groupBy:自定义分组
groupBy (\x y -> (x > 0) == (y > 0)) [-2, -1, 0, 1, 2]
-- [[-2, -1], [0], [1, 2]]
九、特殊函数 #
9.1 iterate #
haskell
-- iterate:重复应用函数
take 5 (iterate (*2) 1) -- [1, 2, 4, 8, 16]
take 5 (iterate (++ "a") "x") -- ["x", "xa", "xaa", "xaaa", "xaaaa"]
9.2 repeat和replicate #
haskell
-- repeat:无限重复
take 5 (repeat 1) -- [1, 1, 1, 1, 1]
-- replicate:重复n次
replicate 5 1 -- [1, 1, 1, 1, 1]
replicate 3 'a' -- "aaa"
9.3 cycle #
haskell
-- cycle:无限循环
take 10 (cycle [1, 2, 3]) -- [1, 2, 3, 1, 2, 3, 1, 2, 3, 1]
take 5 (cycle "ab") -- "ababa"
十、总结 #
列表函数要点:
- 访问:
head、tail、last、init、!! - 判断:
null、elem、all、any - 取舍:
take、drop、takeWhile、dropWhile - 转换:
map、filter、reverse - 折叠:
foldr、foldl、scanr、scanl - 组合:
zip、unzip、concat - 搜索:
find、elemIndex、lookup - 排序:
sort、sortBy、group
掌握列表函数后,让我们继续学习元组。
最后更新:2026-03-27