Swift 序列变形
Swift Sequence Anamorphism
Swift 的标准库是否包含用于 Sequence
或类似内容的 list anamorphism?
列表或序列上的变形与 reduce
函数相反。因此,它不会将序列折叠成单个值,而是向上构建序列。
reduce
取一个初始值,以及一个将序列元素与此组合的函数,returns 取一个最终值。它的签名看起来像这样(为了便于阅读而添加了换行符):
public func reduce<Result>(
_ initialResult: Result,
_ nextPartialResult: (Result, Self.Element) throws -> Result) rethrows
-> Result
序列的变形可能是这样的:
func inflate<State, Element>(
_ initialState: State,
_ generator: @escaping (State) -> (State, Element)?)
-> AnamorphismSequence<State, Element>
通过给它一些初始状态,并告诉它如何将其转换为一个元素和下一个状态,它可以为您构建一个序列。所以,我可以得到一个数组,例如 Array(1..<10)
这样的:
Array(inflate(1) { s in s < 10 ? (s+1, s) : nil })
Swift 有两个变体。两种类型都有私有初始化器,但它们可以使用各自的全局函数生成。
UnfoldSequence<Element, State>
, which is produced by sequence(state:next:)
UnfoldFirstSequence<Element>
which is produced by sequence(first:next:)
前者做不到的,后者不做。它只是一个简化版本,当您不需要单独的状态时使用,而不仅仅是知道前一个元素是什么。
以下是您的 1..<10
示例的实施方式,使用两种方法:
Array(sequence(first: 1) { i in (i < 9) ? (i + 1) : nil })
Array(sequence(state: 1) { state -> Int? in
defer { state += 1 }
return state < 10 ? state : nil
})
您的示例更适合更简单的 sequence(first:next:)
。后者对于生成完美正方形的序列之类的东西更有用:
* 您的维护状态将是完美正方形的正方形(每次展开都会增加 1)
* 您的序列通过将该状态乘以自身(对其进行平方)来生成元素
从技术上讲,您可以使用捕获的局部变量来模拟 UnfoldSequence
的状态,但这有点混乱,而且几乎肯定会更慢。
Swift 的标准库是否包含用于 Sequence
或类似内容的 list anamorphism?
列表或序列上的变形与 reduce
函数相反。因此,它不会将序列折叠成单个值,而是向上构建序列。
reduce
取一个初始值,以及一个将序列元素与此组合的函数,returns 取一个最终值。它的签名看起来像这样(为了便于阅读而添加了换行符):
public func reduce<Result>(
_ initialResult: Result,
_ nextPartialResult: (Result, Self.Element) throws -> Result) rethrows
-> Result
序列的变形可能是这样的:
func inflate<State, Element>(
_ initialState: State,
_ generator: @escaping (State) -> (State, Element)?)
-> AnamorphismSequence<State, Element>
通过给它一些初始状态,并告诉它如何将其转换为一个元素和下一个状态,它可以为您构建一个序列。所以,我可以得到一个数组,例如 Array(1..<10)
这样的:
Array(inflate(1) { s in s < 10 ? (s+1, s) : nil })
Swift 有两个变体。两种类型都有私有初始化器,但它们可以使用各自的全局函数生成。
UnfoldSequence<Element, State>
, which is produced bysequence(state:next:)
UnfoldFirstSequence<Element>
which is produced bysequence(first:next:)
前者做不到的,后者不做。它只是一个简化版本,当您不需要单独的状态时使用,而不仅仅是知道前一个元素是什么。
以下是您的 1..<10
示例的实施方式,使用两种方法:
Array(sequence(first: 1) { i in (i < 9) ? (i + 1) : nil })
Array(sequence(state: 1) { state -> Int? in
defer { state += 1 }
return state < 10 ? state : nil
})
您的示例更适合更简单的 sequence(first:next:)
。后者对于生成完美正方形的序列之类的东西更有用:
* 您的维护状态将是完美正方形的正方形(每次展开都会增加 1)
* 您的序列通过将该状态乘以自身(对其进行平方)来生成元素
从技术上讲,您可以使用捕获的局部变量来模拟 UnfoldSequence
的状态,但这有点混乱,而且几乎肯定会更慢。