函数组合、函数应用、单调函数和一些其他有用事物的一组函数和自定义运算符。
主要是尝试将我最常用/最有用的函数/运算符合并到一处,包括所有这些功能,并提供比类似框架更多的灵活性。
flatMap(>>-、-<<)的运算符
map(<^>)的运算符
将函数应用于参数的运算符(|>、<|)
curry 和 uncurry 函数。
compact 函数。
apply 函数和每个版本包括的运算符 <*> 和 <->。
|> 和 <| - 函数应用运算符考虑一段这样的代码
display(lines(readFromFile("file://allwords.txt")))
很难看到数据是如何流动的,或推理哪个函数首先被调用。使用 |> 运算符,我们可以这样写
"file://allwords.txt" |> readFromFile |> lines |> display
这使得从左到右的数据流动方式变得清晰。
可以以同样的方式使用 <|,只是从右到左。
<^> - map 运算符<^> 是一个运算符,将 Optional 或 CollectionType 上的 map 调用传递出去。
例如
Optionallet optionalInt: Int? = ...
let mapped: String? = String.init <^> optionalInt
CollectionTypelet integers = toInt <^> ["1", "2"]
compact假设你有一个包含可选值的集合(比如 Array,现在我们先考虑 Array)其中的类型签名类似 Array<String?> - compact 函数可以将该数组转换成类似于 Array<String> 的类型
let array = ["Swift", Optional<String>.None, "Kenny"] 的类型是 Array<String?> - 你可以使用 Fission 的 compact 函数轻松地删除可选值,就像这样;compact(array)。
-<< 和 >>- - flatMap 操作符调用到 Optional 或 SequenceType 上的 flatMap
Optionallet string: String? = ...
let flatMapped: Int? = string >>- toInt
或者 let flatMapped: Int? = toInt -<< string
SequenceTypelet allCharaters: [Character] = characters -<< ["hello", "my", "friend"] // 返回包含所有字符串中每个字符的数组
curry 和 uncurrycurry 将一个接受两个参数的函数转换为返回另一个函数的函数 - 这两个函数都只接受一个参数。
这在你想要部分应用一个尚未 curried 的函数时非常有用。例如,这个函数:
func add(first: Double, second: Double) -> Double { return first + second }
如果你为了某种原因需要部分应用此函数(比如你想要传递一个类型为 Double -> Double 的函数到高阶函数中),你可以使用 curry 函数,如下所示:
let curriedAddition = curry(add)(4.0)
并调用函数 3.0 curriedAddition(3.0) - 结果将是 7.0
uncurry 的作用方式与 curry 相反,所以如果你执行 uncurry(curry(add)),你最终得到一个具有与原始 add 函数相同签名的函数。
apply以下是一个使用 apply 的简单示例
let splitCharacters = ["me", "file"].apply([{ return $0.characters.sort() }])
splitCharacters 的值是 [["e", "m"], ["e", "f", "i", "l"]] - 这是从原始数组中的字符串生成的字符数组的数组。
另一个版本的 apply 包括一个可以对接受 inout 参数的函数进行处理,并返回不带返回值的函数,该函数的代码示例为:
var first = ["First"]
first.appendContentsOf(["Second"])通常情况下,你只需要将突变绑定到单个 let 变量的一行语句中,这正是版本的 apply 解决的问题。上面的示例可以写成这样,使用 Fission:
let both = apply(Array.appendContentsOf)(["First"])(["Second"])
或者,使用操作符 <->(以及 <|)
let both = Array.appendContentsOf <-> ["First"] <| ["Second"]