 	}
 }
 
+/// Takes a function and an initial seed value and constructs a list.
+///
+/// unfoldr is the dual to foldr.  Where foldr reduces a list given a function and an initial value,
+/// unfoldr uses the initial value and the function to iteratively build a list.  If list building
+/// should continue the function should return .Some(x, y), else it should return .None.
+public func unfoldr<A, B>(f : B -> Optional<(A, B)>) -> B -> List<A> {
+	return { b in
+		switch f(b) {
+		case .Some(let (a, b2)):
+			return a <| unfoldr(f)(b2)
+		case .None:
+			return List()
+		}
+	}
+}
+
 /// Returns the conjunction of a Boolean list.
 public func and(l : [Bool]) -> Bool {
 	return foldr({$0 && $1})(true)(l)

	return { l in and(l.map(p)) }
}

/// Concatenate a list of lists.
public func concat<A>(xss : [[A]]) -> [A] {
	return foldr({ $0 + $1 })([])(xss)

	return foldl({ $0 * $1 })(1)(l)
}

/// Returns the sum of a list of numbers.
public func sum<N : IntegerType>(l : List<N>) -> N {
	return foldl({ $0 + $1 })(0)(l)
}

/// Returns the product of a list of numbers.
public func product<N : IntegerType>(l : List<N>) -> N {
	return foldl({ $0 * $1 })(1)(l)
}
