3-24.【函数式编程】什么是 Functor?Result 和 Optional 如何实现 Functor 的 map 行为?

4 阅读1分钟

1️⃣ 什么是 Functor

函数式编程中,Functor 是一个可以 映射(map)函数到其内部值的容器类型

定义

  • Functor 是一个容器类型 F<A>(如数组、Optional、Result)
  • 提供方法:
map :: (A -> B) -> F<A> -> F<B>
  • 意思是:给容器里的值应用一个函数,返回新容器,而不改变容器结构

Functor 的三条规律

  1. 保持结构

    • map 不改变容器结构,只改变内部值
  2. 恒等映射

    • container.map { $0 } == container
  3. 组合映射

    • container.map(f).map(g) == container.map { g(f($0)) }

2️⃣ Optional 作为 Functor

Optional 可以看作是一个 可能为空的容器,实现 map

let x: Int? = 5

// map 作用
let y = x.map { $0 * 2 } // Optional(10)
print(y)
  • xOptional<Int>yOptional<Int>
  • 容器结构不变
  • 如果 x = nil,map 不执行函数,直接返回 nil

例子验证 Functor 规律

let a: Int? = 3
let f: (Int) -> Int = { $0 + 1 }
let g: (Int) -> Int = { $0 * 2 }

// 组合映射规律
let left = a.map(f).map(g)
let right = a.map { g(f($0)) }
print(left == right) // true

3️⃣ Result 作为 Functor

Result<Success, Failure> 是一个 可能成功或失败的容器

let success: Result<Int, Error> = .success(10)
let failure: Result<Int, Error> = .failure(NSError(domain: "", code: 1))

// map 作用:只对成功值应用函数
let newSuccess = success.map { $0 * 2 } // .success(20)
let newFailure = failure.map { $0 * 2 } // .failure(...) 不变
  • 只有 success 分支会应用函数
  • failure 保持原有错误 → 保持容器结构
  • 也遵守 Functor 规律:
let f: (Int) -> Int = { $0 + 1 }
let g: (Int) -> Int = { $0 * 2 }

let left = success.map(f).map(g)
let right = success.map { g(f($0)) }
print(left == right) // true

4️⃣ Functor 行为总结

类型Functor map 行为容器结构组合性
Optionalmap 对非 nil 值应用函数,nil 保持不变Optionalmap(f).map(g) == map(g ∘ f)
Resultmap 对 success 应用函数,failure 保持Resultmap(f).map(g) == map(g ∘ f)

关键点

  1. 不改变容器结构
  2. map 只应用于内部值
  3. 可以安全组合多个函数

💡 直观理解

  • Optional = 0 或 1 个值的容器
  • Result = 0 或 1 个成功值 + 可能失败
  • map = “在容器里应用函数,而不碰其他东西”