0Pricing
Lua Academy · 课时

组合函数

串联转换过程。

组合函数 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。

什么是函数组合

函数组合会将两个函数合并为一个函数。组合后的函数先让输入经过第一个函数,再将结果传给第二个函数。

在数学中,这表示为 f(g(x))。函数组合让您可以用小而专注的函数构建大型转换。

组合两个函数

compose 辅助函数接收两个函数,并返回一个新函数。调用它时会先运行 g,然后将结果传给 f。

顺序很重要:内部函数先运行,外部函数再处理它的输出。

local function compose(f, g)
  return function(x)
    return f(g(x))
  end
end

local function inc(n) return n + 1 end
local function dbl(n) return n * 2 end

local incThenDouble = compose(dbl, inc)
print(incThenDouble(3))

顺序很重要

交换参数会改变结果。组合(f, g) 表示先应用 g,再应用 f。

下面的示例展示了先翻倍再递增,与先递增再翻倍会得到不同的结果。

local function compose(f, g) return function(x) return f(g(x)) end end
local function inc(n) return n + 1 end
local function dbl(n) return n * 2 end

print(compose(dbl, inc)(3))
print(compose(inc, dbl)(3))

组合字符串函数

函数组合适用于任意单参数函数,包括字符串转换函数。您可以将去除空白、转换大小写或反转等操作串联为一个可复用的步骤。

这里先运行反转操作,再转换为大写,从而得到一个反转后的大写字符串。

local function compose(f, g) return function(x) return f(g(x)) end end

local shout = compose(string.upper, string.reverse)
print(shout("lua"))

组合多个函数

要串联两个以上的函数,可以编写可变参数的 composeAll。它会像嵌套调用一样,从右到左应用这些函数。

循环会从后向前遍历函数列表,让值依次经过每个函数。

local function composeAll(...)
  local fns = {...}
  return function(x)
    for i = #fns, 1, -1 do
      x = fns[i](x)
    end
    return x
  end
end

local f = composeAll(function(n) return n + 1 end,
  function(n) return n * 2 end,
  function(n) return n - 3 end)
print(f(10))

从右到左

在 composeAll(a, b, c) 中,最右侧的函数 c 会先运行,然后是 b,最后是 a。这与嵌套形式 a(b(c(x))) 一致。

读取这种顺序可能比较困难,因此有些人更喜欢从左到右的管道。

从左到右的管道

pipe 会反转阅读顺序:函数按照书写顺序从左到右运行。对于数据管道,许多人觉得这种方式更容易理解。

循环会从前向后遍历,将每个函数应用于当前值。

local function pipe(...)
  local fns = {...}
  return function(x)
    for i = 1, #fns do
      x = fns[i](x)
    end
    return x
  end
end

local process = pipe(function(n) return n + 1 end,
  function(n) return n * 2 end)
print(process(5))

让管道更易读

使用 pipe 时,各个步骤会按照执行顺序从上到下排列。这使多阶段转换过程能够自我说明。

这里先去掉字符串的前缀,再转换为小写,最后反转;每个步骤都按照实际发生的顺序列出。

local function pipe(...) local fns={...} return function(x) for i=1,#fns do x=fns[i](x) end return x end end

local transform = pipe(string.lower, string.reverse,
  function(s) return "[" .. s .. "]" end)
print(transform("LUA"))

使用闭包进行组合

您可以组合通过部分应用或闭包构建的函数。先构建小型专用函数,再将它们连接起来。

这样可以让每个部分都易于测试,同时由组合表达整体流程。

local function pipe(...) local fns={...} return function(x) for i=1,#fns do x=fns[i](x) end return x end end
local function adder(n) return function(x) return x + n end end
local function muller(n) return function(x) return x * n end end

local calc = pipe(adder(3), muller(10))
print(calc(2))

组合与数据管道

函数组合是数据管道背后的连接纽带。您无需深层嵌套调用,而是只需命名一个组合函数,然后将它应用于多个输入。

它与映射配合得非常好:将组合函数作为每个元素的转换函数传入即可。

local function map(t, f) local o={} for i,v in ipairs(t) do o[i]=f(v) end return o end
local function compose(f, g) return function(x) return f(g(x)) end end

local step = compose(function(n) return n + 1 end, function(n) return n * n end)
local r = map({1, 2, 3, 4}, step)
print(table.concat(r, ", "))

保持函数小巧

函数组合鼓励使用小型的单一用途函数。每个函数只完成一项工作,您可以将它们组合起来形成复杂行为,而无需重复编写逻辑。

这正是函数式设计的核心:构建由微小函数组成的词汇表,再通过组合表达更大的思想。

快速检查

请在回答前仔细追踪执行顺序。

回顾

函数组合会将函数连接起来,使一个函数的输出成为下一个函数的输入。组合(f, g) 会先运行 g,再运行 f,即从右到左;而管道则从左到右运行,更便于阅读。

借助 composeAll 和 pipe,您可以将许多小函数串联成清晰的数据管道,尤其是在与映射配合使用时更加强大。

常见问题解答

「组合函数」课时是免费的吗?

是的 — 「组合函数」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。

「组合函数」这节课中我会学到什么?

串联转换过程。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Lua Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「组合函数」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Lua Academy 课中编写并运行代码吗?

能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 作为值的函数
  2. map、filter、reduce
  3. 部分应用
  4. 组合函数
← 返回 Lua Academy