欢迎来到第三章。在上一章中,你已经在"递归禁地"中历经磨难,学会了如何用灵魂的自我重叠来处理数据。
今天,我们要走出禁地,前往宗门的**"万宝阁"**。在这里,你将继承 λ 门传承万载的三件大威力法宝:Map (造化术) 、Filter (法眼术) 和 Fold (归一术) 。掌握了它们,你将不再需要手动驱动递归,只需祭出法宝,万千数据便会自化其形。
在 Haskell 的世界里,函数不仅是招式,它们本身就是可以被装在锦囊里、作为参数传递给其他法术的"宝物"。这种能操控法术的法术,被称为高阶函数(Higher-Order Functions) 。
3.1 无名法印:Lambda 表达式
在正式使用法宝前,你需要学会凝聚**"无名法印"(Lambda)**。有时候你只需要一个简单的动作(比如"灵力加一"),不需要专门开坛做法(定义函数名)。
-
咒语符号: `` (它看起来像希腊字母 <math xmlns="http://www.w3.org/1998/Math/MathML"> λ \lambda </math>λ)
-
施法示例:
(\x -> x + 1)- 这枚印记接受一个
x,瞬间将其变为x + 1,随用随弃,不留因果。
- 这枚印记接受一个
3.2 第一件法宝:Map(万物造化)
Map 法宝能将一种规则同时映射到成千上万的目标上。它不改变目标的数量,只改变目标的"本质"。
- 用法:
map 招式 目标列表 - 演练: 假设你有一排凡铁
[1, 2, 3],你想通过"点金术"(加 10)将它们化为精金。
Haskell
diff
-- 凡人做法:手动写递归(累得半死)
-- 修仙做法:祭出 Map
map (\x -> x + 10) [1, 2, 3]
-- 结果:[11, 12, 13]
心法: 只要你能定义一个人的升华过程,
map就能升华整个世界。
3.3 第二件法宝:Filter(法眼辨真)
修仙界因果杂乱,并非所有灵气都能为你所用。Filter 法宝能帮你照破虚妄,只留下符合你心境的东西。
- 用法:
filter 判别式 目标列表 - 演练: 从一堆驳杂的灵石中,只选出灵力大于 100 的上品灵石。
Haskell
scss
filter (\stone -> stone > 100) [50, 120, 80, 200]
-- 结果:[120, 200]
心法: 弱水三千,只取一瓢。
filter便是那取水的瓢。
3.4 第三件法宝:Fold(万法归一)
这是三件法宝中最难驾驭、也最强大的**"归一术" 。它能将一整个列表的因果,不断折叠、浓缩,最终炼成一颗"金丹"**(单个值)。
- 用法:
foldr 结合方式 初始值 目标列表 - 演练: 将所有的灵气
[1, 2, 3, 4]凝聚成一个总和。
Haskell
scss
foldr (+) 0 [1, 2, 3, 4]
-- 过程:1 + (2 + (3 + (4 + 0)))
-- 结果:10
心法: 无论是求和、求积,还是寻找最强灵压,皆逃不出"折叠"二字。
foldr是从右往左折叠(顺天应人),foldl是从左往右(逆天改命)。
3.5 护身秘术:柯里化(Currying)
你可能会发现,Haskell 的函数调用不需要括号。这是因为在 Haskell 中,所有法术其实都只有一个参数。
当你施展 add x y 时,实际上是先施展了 add x,它化出了一个"专门加 x"的临时分身,再作用于 y。这叫柯里化。这让你能随时创造出"半成品法术":
Haskell
ini
let addTen = (+ 10) -- 这是一个已经蓄力一半的法术
addTen 5 -- 结果:15
📜 结丹试炼:第三关
现在,请组合使用这三件法宝,完成以下挑战:
- 精英筛选: 给定一组弟子的灵力值
[10, 50, 120, 200, 30],请先选出灵力大于 100 的弟子,然后给他们的灵力每人再加 50 点"宗门奖励"。 - 法力汇总: 使用
foldr算出上述奖励后这群精英弟子的总灵力。
"不再纠结于如何遍历,而是专注于规则的复合。恭喜道友,你的筑基期已至圆满。"
下一章预告: 筑基之后,便是结丹 。我们将触碰 Haskell 最玄妙的门槛------Typeclasses(类型类) 。你将明白,为什么有的法术可以对比大小,而有的法术只能看穿虚实。