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表达式要点:

  1. 基本语法\参数 -> 表达式
  2. 多参数\x y -> 表达式\x -> \y -> 表达式
  3. 高阶函数:作为map、filter、fold的参数
  4. 模式匹配:Lambda中可以使用简单模式
  5. 运算符节(+1)(2*) 等简写形式
  6. 柯里化:多参数函数本质是返回函数的函数
  7. 最佳实践:保持简洁,复杂逻辑使用命名函数

掌握Lambda表达式后,让我们继续学习高阶函数。

最后更新:2026-03-27