Swift 函数式编程:进阶篇

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Swift中的函数式编程:高级水平



Swift最初被设计为多范式语言,这使其成为应用高级函数式编程技术的理想平台。在本文中,我们将探讨超越基本闭包和map/filter/reduce的概念——包括函子、单子、函数组合、柯里化和记忆化。这些工具将帮助您为iOS和macOS应用程序编写更可预测、可测试且更具表现力的代码。



函子和单子:处理上下文



函子是一种实现了map函数的类型,允许对上下文内的值应用变换。在Swift中,经典的函子示例是Optional和Array。



// Optional函子let value: Int? = 42let result = value.map { $0 * 2 } // Optional(84)

// Array函子let numbers = [1, 2, 3]let doubled = numbers.map { $0 * 2 } // [2, 4, 6]


单子是一个具有额外flatMap操作(在Haskell中为>>=)的函子。它允许"展开"嵌套的上下文。Swift通过隐式的Monad协议支持单子,但关键类型(Optional、Result、Async)实现了这一逻辑。



// Optional单子:可能为nil的操作链func parseNumber(_ string: String) -> Int? { return Int(string) }func half(_ number: Int) -> Int? { return number % 2 == 0 ? number / 2 : nil }

let input = "42"let result = input.flatMap(parseNumber).flatMap(half) // Optional(21)

// Result单子用于错误处理enum AppError: Error { case invalidInput }func safeDivide(_ a: Int, _ b: Int) -> Result<Int, AppError> { guard b != 0 else { return .failure(.invalidInput) } return .success(a / b)}

let divisionResult = safeDivide(10, 2).flatMap { safeDivide($0, 1) } // .success(5)


高级应用:创建自定义的单子类型来处理异步操作。



struct Async<T> {    let run: (@escaping (T) -> Void) -> Void        func map<U>(transform: @escaping (T) -> U) -> Async<U> {        return Async<U> { callback in            self.run { value in callback(transform(value)) }        }    }        func flatMap<U>(transform: @escaping (T) -> Async<U>) -> Async<U> {        return Async<U> { callback in            self.run { value in transform(value).run(callback) }        }    }}


函数组合:构建管道



函数组合是通过顺序应用多个函数来创建新函数的过程。在Swift中,这可以通过运算符或闭包来实现。



// 组合运算符precedencegroup CompositionPrecedence {    associativity: left    higherThan: FunctionArrowPrecedence}

infix operator >>> : CompositionPrecedence

func >>>(_ f: @escaping (A) -> B, _ g: @escaping (B) -> C) -> (A) -> C { return { x in g(f(x)) }}

// 示例:验证和格式化let trimWhitespace: (String) -> String = { $0.trimmingCharacters(in: .whitespaces) }let capitalize: (String) -> String = { $0.capitalized }let addExclamation: (String) -> String = { $0 + "!" }

let processString = trimWhitespace >>> capitalize >>> addExclamationprint(processString(" hello world ")) // "Hello World!"


组合在处理数据变换链时特别有用,例如处理网络响应。



// 带错误处理的高级组合typealias ResultFunction = (T) -> Result<U, Error>

func compose(_ f: @escaping ResultFunction<T, U>, _ g: @escaping ResultFunction<U, V>) -> ResultFunction<T, V> { return { input

博客

书籍推荐