3-23.【函数式编程】什么是 Monoid,并给出数组或字符串的 Monoid 实例。

5 阅读2分钟

1️⃣ 什么是 Monoid

函数式编程和抽象代数中,Monoid 是一个具有以下特征的代数结构:

  1. 封闭性(Closure)

    • 对类型 T 的任意两个值进行操作,仍然返回同类型值
    • Swift 示例:数组拼接 [Int] + [Int] -> [Int]
  2. 结合律(Associativity)

    • (a ⊕ b) ⊕ c == a ⊕ (b ⊕ c)
    • 操作顺序不会影响结果
  3. 单位元(Identity / Neutral Element)

    • 存在一个元素 e,使得 a ⊕ e = e ⊕ a = a
    • 对数组 → []
    • 对字符串 → ""

总结:Monoid = 类型 + 二元结合操作 + 单位元


2️⃣ Swift 中的数组 Monoid

  • 类型:[Int][Element]
  • 二元操作:数组拼接 +
  • 单位元:空数组 []
let a = [1, 2]
let b = [3, 4]
let c = [5]

// 闭合性
let ab = a + b          // [1,2,3,4]

// 结合律
let left = (a + b) + c  // [1,2,3,4,5]
let right = a + (b + c) // [1,2,3,4,5]
print(left == right)    // true

// 单位元
let withIdentity = a + []  // [1,2]
print(withIdentity == a)   // true

数组就是一个典型的 Monoid


3️⃣ Swift 中的字符串 Monoid

  • 类型:String
  • 二元操作:字符串拼接 +
  • 单位元:空字符串 ""
let s1 = "Hello, "
let s2 = "World"

// 闭合性
let combined = s1 + s2   // "Hello, World"

// 结合律
let left = (s1 + s2) + "!"   // "Hello, World!"
let right = s1 + (s2 + "!")  // "Hello, World!"
print(left == right)         // true

// 单位元
let withIdentity = s1 + ""   // "Hello, "
print(withIdentity == s1)    // true

字符串拼接也是 Monoid


4️⃣ Monoid 的函数式应用

  1. 可折叠数据结构:可以用 reduce 利用 Monoid 来组合数据
let arrays = [[1,2], [3,4], [5]]
let combined = arrays.reduce([], +) // 使用 Monoid 的单位元 []
print(combined) // [1,2,3,4,5]
  1. 字符串拼接流水线
let words = ["Swift", "is", "fun"]
let sentence = words.reduce("", +)
print(sentence) // "Swiftisfun"
  • reduce 的初始值就是 单位元
  • 二元操作就是 Monoid 的结合操作

5️⃣ 小结

特性数组 Monoid字符串 Monoid
类型[Element]String
操作+ (拼接)+ (拼接)
单位元[]""
结合律(a+b)+c == a+(b+c)(a+b)+c == a+(b+c)
用途合并数组、fold/reduce拼接文本、日志收集

💡 核心思想:Monoid 提供可组合、安全的累加操作,在函数式编程中非常常见。