3-26.【函数式编程】请实现一个函数,将数组 Optional<Int> 链式组合,并在遇到 nil 时返回 nil,体现 Monad 特性。

3 阅读1分钟

1️⃣ 示例需求

  • 输入:[Optional<Int>]
  • 操作:对每个非 nil 值进行一系列转换
  • 遇到 nil → 链式短路,返回 nil
  • 体现 Monad 特性(flatMap 平铺容器,避免嵌套 Optional)

2️⃣ 实现代码

import Foundation

// 示例操作函数:加 10,但如果值为负返回 nil
func addTen(_ x: Int) -> Int? {
    let result = x + 10
    return result >= 0 ? result : nil
}

// 示例操作函数:翻倍,但如果结果 > 100 返回 nil
func double(_ x: Int) -> Int? {
    let result = x * 2
    return result <= 100 ? result : nil
}

// 函数式流水线处理单个 Optional<Int>
func processOptional(_ x: Int?) -> Int? {
    return x
        .flatMap(addTen)   // flatMap 避免 Optional<Optional<Int>>
        .flatMap(double)   // 链式调用
}

// 处理数组 Optional<Int>
func processArray(_ array: [Int?]) -> [Int?] {
    return array.map { processOptional($0) }
}

3️⃣ 使用示例

let input: [Int?] = [5, -20, nil, 50]

let output = processArray(input)

print(output) // [30, nil, nil, nil]

解释

  1. 第一个元素 5

    • addTen(5) → 15
    • double(15) → 30 ✅
  2. 第二个元素 -20

    • addTen(-20) → nil
    • 链式短路 → 返回 nil
  3. 第三个元素 nil

    • flatMap 自动短路 → 返回 nil
  4. 第四个元素 50

    • addTen(50) → 60
    • double(60) → 120 → 超过 100 → 返回 nil

4️⃣ Monad 特性体现

  1. 容器 = Optional<Int>
  2. bind / flatMap = 链式调用
  3. 平铺容器 = 避免 Optional<Optional>
  4. 短路行为 = 遇到 nil → 立即返回,后续操作不执行
Optional(5)
  .flatMap(addTen)   // Optional(15)
  .flatMap(double)   // Optional(30)

Optional(-20)
  .flatMap(addTen)   // nil
  .flatMap(double)   // nil  ← 链式短路

总结

  • 每个操作函数都是 (A) -> Optional<B>
  • flatMap 体现 Monad 的 bind 语义
  • 链式组合避免嵌套 Optional,同时保证短路行为
  • 核心逻辑纯函数,可测试、可组合