跳到主要内容

列表操作

map

映射
对列表中的每一个元素进行同样的处理

map (+1) [1, 2, 3] -- 结果是 [2,3,4]

filter

过滤
用一个谓词函数(返回布尔值的函数)过滤列表

filter (>2) [1, 2, 3] -- True就通过,False就去掉,结果是 [3]

fold

折叠
使用一个处理函数依次逐个地把列表中的所有元素组合成为一个值

-- 0是初始值,表示第一步是0和第一个数进行处理
-- 需要一个b->a->b类型的处理函数

-- foldl从左到右,第一步是0-1
foldl (+) 0 [1, 2, 3] -- 结果是 6

-- foldr从右到左,第一步是3-0,第二步是2-3
foldr (+) 0 [1, 2, 3] -- 结果是 6
foldl (||) True (repeat True) -- repeat生成无限列表
=> never returns!

foldr (||) True (repeat True)
=> True

-- 为什么?
-- foldl = f (f (f init a) b) c
-- foldr = f a (f b (f c init))
-- 可以看到,foldl如果要获得值,要遍历到列表最后一个才行
-- 而foldr在第一步就直接能判断True(因为“或”表达式只要一个为True就为True)
-- 所以,避免用foldl而是使用foldl'

-- 它们的实现
foldl :: (a -> b -> a) -> a -> [b] -> a
foldl f z0 xs0 = lgo z0 xs0
where
lgo z [] = z
lgo z (x:xs) = lgo (f z x) xs -- 递归调用lgo,第一个参数是(f z x),也就是当前步处理过后的数据

-- seq是个魔法
-- seq :: a -> b -> b
-- 第一个参数 (a):这是要被强制求值到弱首范式 (WHNF) 的值
-- 第二个参数 (b):一旦第一个参数被求值,seq 将返回此参数

foldl' :: (a -> b -> a) -> a -> [b] -> a
foldl' f a [] = a
foldl' f a (x:xs) = let a' = f a x in a' `seq` foldl' f a' xs

foldr :: (a -> b -> b) -> b -> [a] -> b
foldr _ z [] = z
foldr f z (x:xs) = f x (foldr f z xs)
-- 一个神秘的puzzle
-- 使用foldr实现foldl
-- id是一个函数,作用是直接输出参数本身

-- 柯里化combinedFunction,使其变成一个接收initial参数的函数
foldLeft f initial accumulator = combinedFunction accumulator
where
-- currentFunction第一步是id,后面是step的嵌套
--
-- 这部分就是currentFunction 这部分就是(f previousValue listItem)
-- vvvvvvvvvvvvvvvvvv vvv
-- \previous_deep -> id(f previous_deep 3)
-- \previous -> ( ) (f previous 2)
-- \initial -> ( ) (f initial 1)
-- 就是将最里层的计算结果依赖上一层的结果,导致整个依赖链条翻转过来了
step listItem currentFunction = \previousValue -> currentFunction (f previousValue listItem)

-- 此函数执行完返回一个\previousValue -> ...的函数
-- 这里的最外层previousValue实际上是initial,最外层listItem是列表第一个元素
combinedFunction = foldr step id accumulator -- initial <-这里被柯里化了,实参传的是initial

-- 同理
foldRight f initial accumulator = combinedFunction accumulator
where
step currentFunction listItem = \previousValue -> currentFunction (f listItem previousValue)
combinedFunction = foldl step id accumulator