Lambda表达式 #
一、Lambda基础 #
1.1 什么是Lambda #
Lambda表达式是匿名函数,使用 \ 语法定义:
haskell
-- Lambda表达式
\x -> x + 1
-- 等价的命名函数
addOne x = x + 1
1.2 Lambda语法 #
haskell
-- 基本形式
\参数 -> 表达式
-- 示例
\x -> x * 2 -- 单参数
\x y -> x + y -- 多参数
\x -> \y -> x + y -- 柯里化形式
1.3 Lambda符号 #
haskell
-- \ 符号类似希腊字母λ
-- -> 表示函数映射
\x -> x + 1
-- 读作:lambda x 映射到 x + 1
二、使用场景 #
2.1 高阶函数参数 #
haskell
-- map中使用
doubleAll :: [Int] -> [Int]
doubleAll xs = map (\x -> x * 2) xs
-- filter中使用
evens :: [Int] -> [Int]
evens xs = filter (\x -> x `mod` 2 == 0) xs
-- fold中使用
sum' :: [Int] -> Int
sum' xs = foldl (\acc x -> acc + x) 0 xs
2.2 一次性函数 #
haskell
-- 一次性使用的函数
result = map (\(x, y) -> x + y) [(1, 2), (3, 4), (5, 6)]
-- [3, 7, 11]
-- 复杂的一次性函数
process = map (\x -> if x > 0 then x else -x) [-2, -1, 0, 1, 2]
-- [2, 1, 0, 1, 2]
2.3 返回函数 #
haskell
-- 返回Lambda
makeAdder :: Int -> (Int -> Int)
makeAdder n = \x -> n + x
-- 使用
add5 = makeAdder 5
add5 10 -- 15
三、多参数Lambda #
3.1 多参数语法 #
haskell
-- 多参数Lambda
\x y -> x + y
-- 等价于柯里化形式
\x -> \y -> x + y
-- 使用
apply :: (Int -> Int -> Int) -> Int -> Int -> Int
apply f x y = f x y
result = apply (\x y -> x * y) 3 4 -- 12
3.2 参数顺序 #
haskell
-- 参数顺序很重要
subtract' = \x y -> x - y
subtract' 10 3 -- 7
-- 翻转参数
subtractFlipped = \y x -> x - y
subtractFlipped 10 3 -- -7
3.3 部分应用 #
haskell
-- 部分应用Lambda
addX = \x -> (\y -> x + y)
-- 使用
addFive = addX 5
addFive 10 -- 15
四、Lambda与模式匹配 #
4.1 简单模式 #
haskell
-- 元组模式
addPair = \(x, y) -> x + y
addPair (3, 4) -- 7
-- 列表模式
firstTwo = \(x:y:_) -> (x, y)
firstTwo [1, 2, 3] -- (1, 2)
4.2 模式匹配限制 #
haskell
-- Lambda中的模式匹配不能有多个分支
-- 错误示例:
-- \x -> case x of
-- 0 -> "zero"
-- _ -> "other"
-- 正确:使用case
describe = \x -> case x of
0 -> "zero"
1 -> "one"
_ -> "other"
4.3 复杂模式 #
haskell
-- 嵌套元组
nested = \((x, y), z) -> x + y + z
nested ((1, 2), 3) -- 6
-- Maybe模式
fromMaybe' = \def -> \case
Nothing -> def
Just x -> x
五、Lambda与运算符 #
5.1 运算符节 #
haskell
-- 左节
(+1) = \x -> x + 1
(2*) = \x -> 2 * x
-- 右节
(1-) = \x -> 1 - x
(/2) = \x -> x / 2
-- 使用
map (+1) [1, 2, 3] -- [2, 3, 4]
map (2*) [1, 2, 3] -- [2, 4, 6]
5.2 中缀函数 #
haskell
-- 使用反引号
add x y = x + y
-- 作为中缀
result = 5 `add` 3 -- 8
-- Lambda作为中缀
result' = 5 `(\x y -> x + y)` 3 -- 8
5.3 函数组合 #
haskell
-- 组合Lambda
composed = (\x -> x * 2) . (\x -> x + 1)
composed 5 -- 12
-- 多个组合
pipeline = show . (*2) . (+1)
pipeline 5 -- "12"
六、Lambda与高阶函数 #
6.1 map #
haskell
-- map使用Lambda
squares = map (\x -> x * x) [1..5]
-- [1, 4, 9, 16, 25]
-- 复杂Lambda
complex = map (\x -> if even x then x `div` 2 else x * 3 + 1) [1..10]
-- [4, 1, 10, 2, 16, 3, 22, 4, 28, 5]
6.2 filter #
haskell
-- filter使用Lambda
positive = filter (\x -> x > 0) [-2, -1, 0, 1, 2]
-- [1, 2]
-- 复杂条件
complexFilter = filter (\x -> x > 0 && even x) [-2, -1, 0, 1, 2, 3, 4]
-- [2, 4]
6.3 fold #
haskell
-- foldl使用Lambda
sum' = foldl (\acc x -> acc + x) 0 [1..5]
-- 15
-- foldr使用Lambda
product' = foldr (\x acc -> x * acc) 1 [1..5]
-- 120
-- 自定义fold操作
concatStrings = foldl (\acc s -> acc ++ ", " ++ s) "" ["a", "b", "c"]
-- ", a, b, c"
6.4 zipWith #
haskell
-- zipWith使用Lambda
sums = zipWith (\x y -> x + y) [1, 2, 3] [4, 5, 6]
-- [5, 7, 9]
-- 复杂操作
pairs = zipWith (\x y -> (x, y)) [1, 2, 3] ['a', 'b', 'c']
-- [(1, 'a'), (2, 'b'), (3, 'c')]
七、Lambda与柯里化 #
7.1 柯里化本质 #
haskell
-- 多参数函数本质是返回函数的函数
add :: Int -> (Int -> Int)
add = \x -> (\y -> x + y)
-- 调用过程
-- add 5 3
-- = (\x -> (\y -> x + y)) 5 3
-- = (\y -> 5 + y) 3
-- = 5 + 3
-- = 8
7.2 部分应用 #
haskell
-- 部分应用创建新函数
multiply :: Int -> Int -> Int
multiply = \x -> \y -> x * y
double :: Int -> Int
double = multiply 2
triple :: Int -> Int
triple = multiply 3
7.3 翻转参数 #
haskell
-- flip函数
flip :: (a -> b -> c) -> b -> a -> c
flip f = \y x -> f x y
-- 使用
subtractFrom = flip (-)
subtractFrom 10 5 -- -5 (实际上是 5 - 10)
八、Lambda技巧 #
8.1 柯里化转换 #
haskell
-- 将元组参数转为柯里化
curry :: ((a, b) -> c) -> a -> b -> c
curry f = \x y -> f (x, y)
-- 将柯里化转为元组参数
uncurry :: (a -> b -> c) -> (a, b) -> c
uncurry f = \(x, y) -> f x y
-- 使用
addPair = uncurry (+)
addPair (3, 4) -- 7
8.2 常用模式 #
haskell
-- 常数函数
const :: a -> b -> a
const x = \_ -> x
-- 身份函数
id :: a -> a
id = \x -> x
-- 组合函数
compose :: (b -> c) -> (a -> b) -> (a -> c)
compose f g = \x -> f (g x)
8.3 延迟计算 #
haskell
-- 使用Lambda延迟计算
lazyValue = \_ -> expensiveComputation
where expensiveComputation = sum [1..1000000]
-- 只在需要时计算
-- lazyValue () 会触发计算
九、实践示例 #
9.1 数据转换 #
haskell
-- 列表转换
transform :: [Int] -> [String]
transform = map (\x ->
if x < 0
then "negative"
else if x == 0
then "zero"
else "positive")
-- 使用
transform [-1, 0, 1] -- ["negative", "zero", "positive"]
9.2 排序 #
haskell
import Data.List (sortBy)
-- 自定义排序
sortByLength :: [[a]] -> [[a]]
sortByLength = sortBy (\xs ys -> compare (length xs) (length ys))
-- 降序排序
sortDesc :: Ord a => [a] -> [a]
sortDesc = sortBy (\x y -> compare y x)
9.3 分组 #
haskell
import Data.List (groupBy)
-- 按条件分组
groupBySign :: [Int] -> [[Int]]
groupBySign = groupBy (\x y -> (x > 0) == (y > 0))
-- 按首字母分组
groupByFirstChar :: String -> [String]
groupByFirstChar = groupBy (\x y -> x == y)
9.4 函数生成器 #
haskell
-- 生成比较函数
makeComparator :: (a -> a -> Ordering) -> a -> a -> Bool
makeComparator cmp = \x y -> cmp x y == GT
-- 生成验证函数
makeValidator :: (a -> Bool) -> a -> Maybe a
makeValidator p = \x -> if p x then Just x else Nothing
十、Lambda最佳实践 #
10.1 可读性 #
haskell
-- 好:简单Lambda
map (+1) xs
-- 好:命名函数更清晰
addOne x = x + 1
map addOne xs
-- 不好:复杂Lambda难以阅读
map (\x -> let y = x * 2 in if y > 10 then y else 0) xs
-- 好:使用命名函数
process x = let y = x * 2 in if y > 10 then y else 0
map process xs
10.2 避免过度嵌套 #
haskell
-- 不好:嵌套Lambda
result = map (\x -> map (\y -> x + y) [1, 2, 3]) [4, 5]
-- 好:使用组合
result' = map (\x -> map (x +) [1, 2, 3]) [4, 5]
-- 更好:使用列表推导
result'' = [[x + y | y <- [1, 2, 3]] | x <- [4, 5]]
10.3 类型签名 #
haskell
-- Lambda通常不需要类型签名
-- 但复杂Lambda可以添加注释
process :: [Int] -> [Int]
process = map (\x -> x * 2) -- 类型推断为 Int -> Int
十一、总结 #
Lambda表达式要点:
- 基本语法:
\参数 -> 表达式 - 多参数:
\x y -> 表达式或\x -> \y -> 表达式 - 高阶函数:作为map、filter、fold的参数
- 模式匹配:Lambda中可以使用简单模式
- 运算符节:
(+1)、(2*)等简写形式 - 柯里化:多参数函数本质是返回函数的函数
- 最佳实践:保持简洁,复杂逻辑使用命名函数
掌握Lambda表达式后,让我们继续学习高阶函数。
最后更新:2026-03-27