函数组合、函数应用、单调函数和一些其他有用事物的一组函数和自定义运算符。
主要是尝试将我最常用/最有用的函数/运算符合并到一处,包括所有这些功能,并提供比类似框架更多的灵活性。
flatMap
(>>-
、-<<
)的运算符
map
(<^>
)的运算符
将函数应用于参数的运算符(|>
、<|
)
curry
和 uncurry
函数。
compact
函数。
apply
函数和每个版本包括的运算符 <*>
和 <->
。
|>
和 <|
- 函数应用运算符考虑一段这样的代码
display(lines(readFromFile("file://allwords.txt")))
很难看到数据是如何流动的,或推理哪个函数首先被调用。使用 |>
运算符,我们可以这样写
"file://allwords.txt" |> readFromFile |> lines |> display
这使得从左到右的数据流动方式变得清晰。
可以以同样的方式使用 <|
,只是从右到左。
<^>
- map
运算符<^>
是一个运算符,将 Optional
或 CollectionType
上的 map
调用传递出去。
例如
Optional
let optionalInt: Int? = ...
let mapped: String? = String.init <^> optionalInt
CollectionType
let 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
Optional
let string: String? = ...
let flatMapped: Int? = string >>- toInt
或者 let flatMapped: Int? = toInt -<< string
SequenceType
let allCharaters: [Character] = characters -<< ["hello", "my", "friend"] // 返回包含所有字符串中每个字符的数组
curry
和 uncurry
curry
将一个接受两个参数的函数转换为返回另一个函数的函数 - 这两个函数都只接受一个参数。
这在你想要部分应用一个尚未 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"]