预言 3.0.0

预言 3.0.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最后发布2017年2月
SwiftSwift 版本3.0
SPM支持 SPM

Kyle FullerNikita Leonov 维护。



预言 3.0.0

  • Rob Rix

预言

这是一个 Swift 微框架,提供了一系列我在许多其他框架中使用的简单函数。而不是为每个用户重新实现这些函数,我将它们收集在这里。

值得注意的是,此框架不提供任何新类型,也不提供操作自定义类型的函数;这些可能属于它们自己的微框架。

目录

画廊

预言的函数无限有用。这里展示的是它们可以做的几件事情中的一小部分。

id

id 作为参数传递给 StreamflattenMap 方法,可以将 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)]

firstsecond

从一个元组中获取一个值是常见的操作,可以使用 firstsecond 函数来表示。操作符相应地为两个元素的元组提供第一和第二个值。

[(0,0), (5, 1), (9, 2)].map(second) // => [0, 1, 2]

文档

完整的 API 文档位于源文件中。

集成

  1. 将此存储库作为子模块添加,检查其依赖项,并且/或者如果您使用 carthage 管理依赖项,则将其添加到 Cartfile 中。
  2. 将 `Prelude.xcodeproj` 拖入您的项目或工作区。
  3. 将您的目标与 `Prelude.framework` 链接。
  4. 应用目标应确保将框架复制到他们的应用程序捆绑包中。相反,框架目标应要求应用程序链接它们包括 Prelude。