Skip to content

Instantly share code, notes, and snippets.

@mehmetfarhan
Last active July 5, 2020 05:53
Show Gist options
  • Save mehmetfarhan/51046c93efdefe2cdf77358e1384c162 to your computer and use it in GitHub Desktop.
Save mehmetfarhan/51046c93efdefe2cdf77358e1384c162 to your computer and use it in GitHub Desktop.
Combinable & EmptyInitilizable
// MARK: - Using Protocols
protocol EmptyInitilizable {
init()
}
protocol Combinable {
func combine(with other: Self) -> Self
}
// MARK: EmptyInitilizable
extension Optional: EmptyInitilizable {
init() { self = nil }
}
extension Int: EmptyInitilizable { }
// MARK: Combinable
extension Int: Combinable {
func combine(with other: Int) -> Int { self + other }
}
extension Optional: Combinable {
func combine(with other: Optional) -> Optional { self ?? other }
}
extension Array where Element: Combinable {
func redunce(_ initial: Element) -> Element {
return self.reduce(initial) { $0.combine(with: $1) }
}
}
// MARK: Combinable & EmptyInitilizable
extension Array where Element: Combinable & EmptyInitilizable {
func reduce() -> Element {
self.reduce(Element()) { $0.combine(with: $1) }
}
}
extension Array {
func reduce<Result: EmptyInitilizable>(_ accumulation: (Result, Element) -> Result) -> Result {
return self.reduce(Result(), accumulation)
}
}
[1, 2, 3].reduce(0, +)
[1, 2, 3].reduce(+) // Using EmptyInitilizable
[1, 2, 3].redunce(0) // Using Combinable
[1, 2, 3].reduce() // Combinable & EmptyInitilizable
[nil, 2, 3].reduce() // Combinable & EmptyInitilizable
// MARK: Using Struct
struct Combining<A> {
let combine: (A, A) -> A
}
extension Array /* where Element: Combinable */ {
func reduce(_ initial: Element, _ combining: Combining<Element>) -> Element {
return self.reduce(initial, combining.combine)
}
}
let sum = Combining<Int>(combine: +)
[1, 2, 3, 4].reduce(0, sum)
let product = Combining<Int>(combine: *)
[1, 2, 3, 4].reduce(1, product)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment