//  Copyright © 2015 Rob Rix. All rights reserved.

extension CollectionType {
	public var uncons: (first: SubSequence._Element, rest: SubSequence)? {
		if !isEmpty {
			let some = self[startIndex..<startIndex.advancedBy(1)]
			return (first: some[some.startIndex], rest: dropFirst())
		}
		return nil
	}

	public var rest: SubSequence {
		return isEmpty
			? self[startIndex..<endIndex]
			: dropFirst()
	}
}

extension CollectionType where SubSequence: CollectionType, SubSequence.SubSequence == SubSequence {
	public var conses: AnyGenerator<(first: SubSequence._Element, rest: SubSequence)> {
		var current = uncons
		return anyGenerator {
			let next = current
			current = current?.rest.uncons
			return next
		}
	}
}


extension CollectionType where SubSequence == Self {
	public func fold<Out>(initial: Out, @noescape combine: (Generator.Element, Out) -> Out) -> Out {
		return first.map {
			combine($0, dropFirst().fold(initial, combine: combine))
		} ?? initial
	}
}

//  Copyright © 2015 Rob Rix. All rights reserved.

extension CollectionType {
	public var uncons: (first: SubSequence._Element, rest: SubSequence)? {
		if !isEmpty {
			let some = self[startIndex..<startIndex.advancedBy(1)]
			return (first: some[some.startIndex], rest: dropFirst())
		}
		return nil
	}

	public var rest: SubSequence {
		return isEmpty
			? self[startIndex..<endIndex]
			: dropFirst()
	}
}

extension CollectionType where SubSequence: CollectionType, SubSequence.SubSequence == SubSequence {
	public var conses: AnyGenerator<(first: SubSequence._Element, rest: SubSequence)> {
		var current = uncons
		return anyGenerator {
			let next = current
			current = current?.rest.uncons
			return next
		}
	}

	public func fold<Out>(initial: Out, @noescape combine: (SubSequence._Element, Out) -> Out) -> Out {
		return self[indices].fold(initial, combine: combine)
	}
}


extension CollectionType where SubSequence == Self {
	public func fold<Out>(initial: Out, @noescape combine: (Generator.Element, Out) -> Out) -> Out {
		return first.map {
			combine($0, dropFirst().fold(initial, combine: combine))
		} ?? initial
	}
}

--- 
+++ 
@@ -25,10 +25,6 @@
 			return next
 		}
 	}
-
-	public func fold<Out>(initial: Out, @noescape combine: (SubSequence._Element, Out) -> Out) -> Out {
-		return self[indices].fold(initial, combine: combine)
-	}
 }
 
 
Revert "Add a fold overload that will work on Array."

This reverts commit 5c55ab336abbfe9aaf94ca2066b110cfbf475c39.
