测试已测试 | ✓ |
语言语言 | SwiftSwift |
许可证 | MIT |
发布最后发布 | 2017年2月 |
SwiftSwift 版本 | 3.0 |
SPM支持 SPM | ✗ |
由 Kyle Fuller、Nikita Leonov 维护。
这是一个 Swift 微框架,提供了一系列我在许多其他框架中使用的简单函数。而不是为每个用户重新实现这些函数,我将它们收集在这里。
值得注意的是,此框架不提供任何新类型,也不提供操作自定义类型的函数;这些可能属于它们自己的微框架。
预言的函数无限有用。这里展示的是它们可以做的几件事情中的一小部分。
id
将 id
作为参数传递给 Stream
的 flattenMap
方法,可以将 Stream
的嵌套元素展开成所有元素的流
func flatten<T>(stream: Stream<Stream<T>>) -> Stream<T> {
return stream.flattenMap(id)
}
const
将 const
的结果传递给 Either
可以方便地将其转换为 Optional<T>
let result: Either<NSError, String> = …
if let string = result.either(const(nil), id) {
println("ohai \($0)")
}
>>>
和 <<<
左到右和右到左的组合操作符(分别对应于 >>>
和 <<<
)可以将操作组合起来
let repl: File -> String = readLine >>> parseString >>> evaluateAST >>> toString
while true {
println(repl(standardInput))
}
fix
您可以使用 fix
创建一个递归调用自己的匿名函数
let factorial = fix { recur in
{ n in n > 0 ? n * recur(n - 1) : 1 }
}
|>
和 <|
前向和后向应用操作符(分别对应于 |>
和 <|
)将他们指向的一侧上的函数应用于另一侧的值。
这有时可以使代码更易读。特别适用于前向应用操作符。 `x |> f
` 等价于 `f(x)
`,但它读取数据流动的方向。当函数名较长时,这种优势更为明显。
100 |> toString |> count // => 3
// this is equivalent to
countElements(toString(100))
反向应用与这种方向相反——`f <| x
` 并非对 `f(x)
` 有任何改进。然而,与正向应用不同的是,`<|
` 可以对它们的第一个操作数应用二进制和三元函数。这使您能够创建类似 Haskell 的操作符部分 的内容。
let successor: Int -> Int = (+) <| 1
successor(3) // => 4
map([1, 2, 3], (*) <| 2) // => [2, 4, 6]
您还可以将 `|>
` 和 `<|
` 与 flip
结合使用,通过链式的高级函数(如 `sorted
`、`map
` 和 `reduce
`)传递数据。
let result =
[66, 78, 1, 95, 76]
|> (flip(sorted) <| (<)) // sort in ascending order
|> (flip(map) <| toString) // make them into strings
|> String.join(", ") // comma-separate them
let sum: [Int] -> Int = flip(reduce) <| (+) <| 0
由于 Swift 函数也可以应用于它们的参数元组,因此您也可以通过在另一侧放置一个元组,使用二进制、三元等函数与 `|>
` 和 `<|
`。
(1, 2) |> (+) // => 3
curry
Currying 将一个具有 >1 个参数的函数转换为返回一个返回一个参数的函数,依此类推。也就是说,给定 `(T, U) -> V
`,currying 返回 `T -> U -> V
`。
这在创建更复杂的函数(如 `<|
`)时特别有用。
flip
使用例如 `-
` 和 `/
` 这样的非交换运算符进行假操作符部分时,<|
可能会有点令人惊讶:`(-) <| 1
` 表示 `{ 1 - $0 }
`,这与 `{ $0 - 1 }
` 非常不同。您可以使用 `flip
` 来生成后者。
map([1, 2, 3], (-) <| 1) // => [0, -1, -2]
map([1, 2, 3], flip(-) <| 1) // => [0, 1, 2]
&&&
Optional
有一个 map
方法,这正是当您想要对一个非 nil
的值应用一个函数时所需的,否则返回 nil
。当您有两个 Optional
值时,您可以使用 `&&;&
` 来合并它们。
let (x: Int?, y: Int?) = (2, 2)
(x &&& y).map(+) // => .Some(4)
swap
Swift 的元组非常方便,但有时您获得的是反方向。`swap
` 在元组上所做的与 `flip
` 在函数上所做的相同:它反转它们的顺序。
map(enumerate("hello"), swap) // => [(h, 0), (e, 1), (l, 2), (l, 3), (o, 4)]
first
和 second
从一个元组中获取一个值是常见的操作,可以使用 first
和 second
函数来表示。操作符相应地为两个元素的元组提供第一和第二个值。
[(0,0), (5, 1), (9, 2)].map(second) // => [0, 1, 2]
完整的 API 文档位于源文件中。
Prelude.xcodeproj
` 拖入您的项目或工作区。Prelude.framework
` 链接。