Last active
December 9, 2015 20:34
-
-
Save HenningBrandt/fd9a46d5abbc3b39a35e to your computer and use it in GitHub Desktop.
An implementation of fold in Swift with a few usage examples. Blog article corresponding to it: http://thepurecoder.com/functional-swift-fold-it-baby/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension Array { | |
func empty() -> Bool { | |
return self.count == 0 | |
} | |
var head: Element? { | |
get { | |
return self.first | |
} | |
} | |
var tail: Array<Element>? { | |
get { | |
if self.empty() { return nil } | |
return Array(self.dropFirst()) | |
} | |
} | |
} | |
func foldl<A,B>(acc: A, list: Array<B>, f: (A, B) -> A) -> A { | |
if list.empty() { return acc } | |
return foldl(f(acc, list.head!), list: list.tail!, f: f) | |
} | |
func sum(list: Array<Int>) -> Int { | |
return foldl(0, list: list, f: (+)) | |
} | |
extension Array { | |
func push(elem: Element) -> Array<Element> { | |
var tmpArray = Array(self) | |
tmpArray.insert(elem, atIndex: 0) | |
return Array(tmpArray) | |
} | |
} | |
func reverse<T>(list: Array<T>) -> Array<T> { | |
return foldl(Array<T>(), list: list, f: { return $0.push($1) }) | |
} | |
func maximum(list: Array<Int>) -> Int { | |
return foldl(0, list: list, f: max) | |
} | |
func universalQuantifier(list: Array<Bool>) -> Bool { | |
return foldl(true, list: list, f: { $0 && $1 }) | |
} | |
func existencialQuantifier(list: Array<Bool>) -> Bool { | |
return foldl(false, list: [false, true, true], f: { $0 || $1 }) | |
} | |
func fac(n: Int) -> Int { | |
return foldl(1, list: Array(1...n), f: (*)) | |
} | |
extension Array { | |
func _append(elem: Element) -> Array<Element> { | |
var arr = Array(self) | |
arr.append(elem) | |
return Array(arr) | |
} | |
} | |
func _filter<T>(list: Array<T>, pred: (T -> Bool)) -> Array<T> { | |
return foldl(Array<T>(), list: list, f: { pred($1) ? $0._append($1) : $0 }) | |
} | |
func _map<A,B>(list: Array<A>, mf: (A -> B)) -> Array<B> { | |
return foldl(Array<B>(), list: list, f: { $0._append(mf($1)) }) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment