Skip to content

Instantly share code, notes, and snippets.

@oisdk
Created July 13, 2015 20:17
Show Gist options
  • Save oisdk/f8edf4b70e515373a6ac to your computer and use it in GitHub Desktop.
Save oisdk/f8edf4b70e515373a6ac to your computer and use it in GitHub Desktop.
// Equivalent to foldM
extension Sliceable where
SubSlice : Sliceable,
SubSlice.Generator.Element == Generator.Element,
SubSlice.SubSlice == SubSlice {
func flatReduce
<U, S : SequenceType where S.Generator.Element == U>
(initial: U, @noescape combine: (U, Generator.Element) -> S) -> [U] {
return first.map {
combine(initial, $0).flatMap {
dropFirst(self).flatReduce($0, combine: combine)
}
} ?? [initial]
}
func flatReduce<U>(initial: U, @noescape combine: (U, Generator.Element) -> U?) -> U? {
return first.map {
combine(initial, $0).flatMap {
dropFirst(self).flatReduce($0, combine: combine)
}
} ?? initial
}
}
// Equivalent to filterM
extension Sliceable where
SubSlice : Sliceable,
SubSlice.Generator.Element == Generator.Element,
SubSlice.SubSlice == SubSlice {
func flatFilter
<S : SequenceType where S.Generator.Element == Bool>
(isElement: Generator.Element -> S) -> [[Generator.Element]] {
return first.map {
element in
let answers = isElement(element)
return dropFirst(self).flatFilter(isElement).flatMap {
rest in
answers.map {
($0 ? [element] : []) + rest
}
}
} ?? [[]]
}
func flatFilter(isElement: Generator.Element -> Bool?) -> [Generator.Element]? {
return first.map {
element in
let answers = isElement(element)
return dropFirst(self).flatFilter(isElement).flatMap {
rest in
answers.map {
($0 ? [element] : []) + rest
}
}
} ?? []
}
}
[1, 2, 3].flatFilter {_ in [true, false]} // [[1, 2, 3], [2, 3], [1, 3], [3], [1, 2], [2], [1], []]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment