<commit_before>//  Copyright (c) 2015 <NAME>. All rights reserved.

/// A composite error.
public enum Error<I: ForwardIndexType>: CustomStringConvertible {
	indirect case Branch(String, I, [Error])

	/// Constructs a leaf error, e.g. for terminal parsers.
	public static func leaf(reason: String, _ index: I) -> Error {
		return .Branch(reason, index, [])
	}

	public static func withReason(reason: String, _ index: I) -> (Error, Error) -> Error {
		return { Error(reason: reason, index: index, children: [$0, $1]) }
	}

	public init(reason: String, index: I, children: [Error]) {
		self = .Branch(reason, index, children)
	}


	public var reason: String {
		switch self {
		case let .Branch(s, _, _):
			return s
		}
	}

	public var index: I {
		switch self {
		case let .Branch(_, i, _):
			return i
		}
	}

	public var children: [Error] {
		switch self {
		case let .Branch(_, _, c):
			return c
		}
	}


	public var depth: Int {
		return 1 + ((children.sort { $0.depth < $1.depth }).last?.depth ?? 0)
	}


	// MARK: Printable
	
	public var description: String {
		return describe(0)
	}

	private func describe(n: Int) -> String {
		let description = String(count: n, repeatedValue: "\t" as Character) + "\(index): \(reason)"
		if children.count > 0 {
			return description + "\n" + children.lazy.map { $0.describe(n + 1) }.joinWithSeparator("\n")
		}
		return description
	}
}


/// MARK: - Annotations

/// Adds a name to parse errors.
public func describeAs<C: CollectionType, T>(name: String)(_ parser: Parser<C, T>.Function) -> Parser<C, T>.Function {
	return { input, index in
		parser(input, index).either(
			ifLeft: { Either.left(Error(reason: "\(name): \($0.reason)", index: $0.index, children: $0.children)) },
			ifRight: Either.right)
	}
}


import Either
import Prelude<commit_msg>Add an annotation operator.<commit_after>//  Copyright (c) 2015 <NAME>. All rights reserved.

/// A composite error.
public enum Error<I: ForwardIndexType>: CustomStringConvertible {
	indirect case Branch(String, I, [Error])

	/// Constructs a leaf error, e.g. for terminal parsers.
	public static func leaf(reason: String, _ index: I) -> Error {
		return .Branch(reason, index, [])
	}

	public static func withReason(reason: String, _ index: I) -> (Error, Error) -> Error {
		return { Error(reason: reason, index: index, children: [$0, $1]) }
	}

	public init(reason: String, index: I, children: [Error]) {
		self = .Branch(reason, index, children)
	}


	public var reason: String {
		switch self {
		case let .Branch(s, _, _):
			return s
		}
	}

	public var index: I {
		switch self {
		case let .Branch(_, i, _):
			return i
		}
	}

	public var children: [Error] {
		switch self {
		case let .Branch(_, _, c):
			return c
		}
	}


	public var depth: Int {
		return 1 + ((children.sort { $0.depth < $1.depth }).last?.depth ?? 0)
	}


	// MARK: Printable
	
	public var description: String {
		return describe(0)
	}

	private func describe(n: Int) -> String {
		let description = String(count: n, repeatedValue: "\t" as Character) + "\(index): \(reason)"
		if children.count > 0 {
			return description + "\n" + children.lazy.map { $0.describe(n + 1) }.joinWithSeparator("\n")
		}
		return description
	}
}


/// MARK: - Annotations

/// Adds a name to parse errors.
public func describeAs<C: CollectionType, T>(name: String)(_ parser: Parser<C, T>.Function) -> Parser<C, T>.Function {
	return { input, index in
		parser(input, index).either(
			ifLeft: { Either.left(Error(reason: "\(name): \($0.reason)", index: $0.index, children: $0.children)) },
			ifRight: Either.right)
	}
}


// MARK: - Operators

infix operator <?> {
	associativity left
	precedence 90
}


import Either
import Prelude
{'fraction_non_alphanumeric': 0.15430427720628045, 'fraction_numerical': 0.009745533297238766, 'mean_word_length': 3.3368544600938965, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6468080', 'n_tokens_mistral': 1360, 'n_tokens_neox': 1241, 'n_words': 388}