 	return { memoized()($0, $1) }
 }
 
-
-// MARK: - Private
-
-/// Returns `true` iff `collection` contains all of the elements in `needle` in-order and contiguously, starting from `index`.
-func containsAt<C1: Collection, C2: Collection>(_ collection: C1, index: C1.Index, needle: C2) -> Bool where C1.Iterator.Element == C2.Iterator.Element, C1.Iterator.Element: Equatable {
-	var index1 = index
-	var index2 = needle.startIndex
-	
-	while index1 < collection.endIndex && index2 < needle.endIndex {
-		if collection[index1] != needle[index2] {
-			return false
-		}
-		
-		index1 = collection.index(after: index1)
-		index2 = needle.index(after: index2)
-	}
-	
-	if index2 < needle.endIndex {
-		return false
-	}
-	
-	return true
-}
-
 // Returns a parser that satisfies the given predicate
 public func satisfy(_ pred: @escaping (Character) -> Bool) -> Parser<String.CharacterView, Character>.Function {
 	return tokenPrim(updatePosCharacter, pred)


public prefix func %(literal: String) -> Parser<String.CharacterView, String>.Function {
	return { input, sourcePos in
		if containsAt(input, index: sourcePos.index, needle: literal.characters) {
			return .success((literal, updatePosString(input, sourcePos, literal)))
		} else {
			return .failure(.leaf("expected \(literal)", sourcePos))

/// This overload enables e.g. `%"xyz"` to produce `String -> (String, String)`.
public prefix func % <C: Collection> (literal: C) -> Parser<C, C>.Function where C.Iterator.Element: Equatable {
	return { input, sourcePos in
		if input[sourcePos.index...].starts(with: literal) {
			return .success((literal, updateIndex(sourcePos, input.index(sourcePos.index, offsetBy: literal.count))))
		} else {
			return .failure(.leaf("expected \(literal)", sourcePos))
