Swift 中的函数式编程
Swiftz 是一个用于函数式编程的 Swift 库。
它定义了函数式数据结构、函数、惯用法和扩展,用于增强 Swift 标准库。
对于一种将函数式原语引入任何代码库的更小、更简单的方法,请参阅 Swiftx。
Swiftz 的灵感来源于许多函数式库和语言。其中最主要的是 Scalaz、Prelude/Base、SML Basis 以及 OCaml 标准库。该库的元素依赖于其组合语义,以便在 Swift 中更清晰地表达声明式思想。
Swiftz 是 Swiftx 的一个真正的超集,它实现了更高级别的数据类型,如 Arrows、Lists、HLists,以及许多对于在使用类型系统最大程度支持下进行编程至关重要的类型类。
为了说明这些抽象概念的用法,请看以下几个例子
Lists (列表)
import struct Swiftz.List
//: Cycles a finite list of numbers into an infinite list.
let finite : List<UInt> = [1, 2, 3, 4, 5]
let infiniteCycle = finite.cycle()
//: Lists also support the standard map, filter, and reduce operators.
let l : List<Int> = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let twoToEleven = l.map(+1) // [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
let even = l.filter((==0) • (%2)) // [2, 4, 6, 8, 10]
let sum = l.reduce(curry(+), initial: 0) // 55
//: Plus a few more.
let partialSums = l.scanl(curry(+), initial: 0) // [0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
let firstHalf = l.take(5) // [1, 2, 3, 4, 5]
let lastHalf = l.drop(5) // [6, 7, 8, 9, 10]
Semigroups 和 Monoids (半群和幺半群)
let xs = [1, 2, 0, 3, 4]
import protocol Swiftz.Semigroup
import func Swiftz.sconcat
import struct Swiftz.Min
//: The least element of a list can be had with the Min Semigroup.
let smallestElement = sconcat(Min(2), t: xs.map { Min($0) }).value() // 0
import protocol Swiftz.Monoid
import func Swiftz.mconcat
import struct Swiftz.Sum
//: Or the sum of a list with the Sum Monoid.
let sum = mconcat(xs.map { Sum($0) }).value() // 10
import struct Swiftz.Product
//: Or the product of a list with the Product Monoid.
let product = mconcat(xs.map { Product($0) }).value() // 0
Arrows (箭头)
import struct Swiftz.Function
import struct Swiftz.Either
//: An Arrow is a function just like any other. Only this time around we
//: can treat them like a full algebraic structure and introduce a number
//: of operators to augment them.
let comp = Function.arr(+3) • Function.arr(*6) • Function.arr(/2)
let both = comp.apply(10) // 33
//: An Arrow that runs both operations on its input and combines both
//: results into a tuple.
let add5AndMultiply2 = Function.arr(+5) &&& Function.arr(*2)
let both = add5AndMultiply2.apply(10) // (15, 20)
//: Produces an Arrow that chooses a particular function to apply
//: when presented with the side of an Either.
let divideLeftMultiplyRight = Function.arr(/2) ||| Function.arr(*2)
let left = divideLeftMultiplyRight.apply(.Left(4)) // 2
let right = divideLeftMultiplyRight.apply(.Right(7)) // 14
Operators (运算符)
有关支持的运算符列表,请参阅 Operators (运算符)。
要将 Swiftz 添加到您的应用程序
使用 Carthage
- 将 Swiftz 添加到您的 Cartfile
- 运行
carthage update
- 将 Swiftz 的相关副本拖到您的项目中。
- 展开 “Link Binary With Libraries (链接二进制文件与库)” 阶段
- 单击 + 并添加 Swiftz
- 单击左上角的 + 以添加 “Copy Files (复制文件)” 构建阶段
- 将目录设置为
Frameworks
- 单击 + 并添加 Swiftz
使用 Git Submodules
- 将 Swiftz 克隆为子模块到您选择的目录中
- 运行
git submodule init -i --recursive
- 将
Swiftz.xcodeproj
或Swiftz-iOS.xcodeproj
作为子项目拖到您的项目树中 - 在您项目的 “Build Phases (构建阶段)” 下,展开 “Target Dependencies (目标依赖项)”
- 单击 + 并添加 Swiftz
- 展开 “Link Binary With Libraries (链接二进制文件与库)” 阶段
- 单击 + 并添加 Swiftz
- 单击左上角的 + 以添加 “Copy Files (复制文件)” 构建阶段
- 将目录设置为
Frameworks
- 单击 + 并添加 Swiftz
使用 Swift Package Manager
- 在您项目的
Package
定义中,将 Swiftz 添加到您的Package.swift
let package = Package(
name: "MyProject",
...
dependencies: [
.package(url: "https://github.com/typelift/Swiftz.git", from: "0.0.0")
...
],
targets: [
.target(
name: "MyProject",
dependencies: ["Swiftz"]),
...
]
)
Swiftz 支持 OS X 10.9+ 和 iOS 8.0+。
Swiftz 在 BSD 许可证下发布。