<commit_before>import Abstract

// MARK: - Definition

// sourcery: concrete = "Result"
// sourcery: context = "ErrorType"
// sourcery: contextRequiredProtocols = "Error"
// sourcery: map, flatMap, zip, <*>, lift, lift+, lift-, lift*, lift/, liftPrefix-
// sourcery: transformer1, transformer2, transformer3
public protocol ResultType: PureConstructible {
	associatedtype ErrorType: Error
	init(_ error: ErrorType)
	init()
	func run <A> (ifSuccess: (ElementType) -> A, ifFailure: (ErrorType) -> A, ifCancel: () -> A) -> A
}

// MARK: - Concrete

// sourcery: context
// sourcery: contextRequiredProtocols = "Error"
// sourcery: functorLaws, applicativeLaws, monadLaws
// sourcery: fixedContextForLawsAndTests = "AnyError"
// sourcery: fixedTypesForTests = "Int"
// sourcery: arbitrary
// sourcery: arbitraryAdditionalParameterForGeneric = "E"
// sourcery: arbitraryAdditionalGenericParameterProtocols = "Error & Arbitrary"
public enum Result<T,E>: ResultType where E: Error {
	public typealias ElementType = T
	public typealias ErrorType = E

	case success(T)
	case failure(E)
	case cancel

	public init(_ value: ElementType) {
		self = .success(value)
	}

	public init(_ error: ErrorType) {
		self = .failure(error)
	}

	public init() {
		self = .cancel
	}

	public func run<A>(ifSuccess: (T) -> A, ifFailure: (E) -> A, ifCancel: () -> A) -> A {
		switch self {
		case .success(let value):
			return ifSuccess(value)
		case .failure(let error):
			return ifFailure(error)
		case .cancel:
			return ifCancel()
		}
	}

	public func get() throws -> ElementType? {
		switch self {
		case .success(let value):
			return value
		case .failure(let error):
			throw error
		case .cancel:
			return nil
		}
	}
}

extension Result where T: Equatable, E: Equatable {
	public static func == (left: Result, right: Result) -> Bool {
		switch (left,right) {
		case (.success(let leftValue), .success(let rightValue)):
			return leftValue == rightValue
		case (.failure(let leftError), .failure(let rightError)):
			return leftError == rightError
		case (.cancel,.cancel):
			return true
		default:
			return false
		}
	}
}

// MARK: - Functor

extension ResultType {
	public func map <A> (_ transform: @escaping (ElementType) -> A) -> Result<A,ErrorType> {
		return run(
			ifSuccess: { .success(transform($0)) },
			ifFailure: { .failure($0) },
			ifCancel: { .cancel })
	}
}

// MARK: - Joined

extension ResultType where ElementType: ResultType, ElementType.ErrorType == ErrorType {
	public var joined: Result<ElementType.ElementType,ErrorType> {
		return run(
			ifSuccess: { $0.run(
				ifSuccess: { .success($0) },
				ifFailure: { .failure($0) },
				ifCancel: { .cancel }) },
			ifFailure: { .failure($0) },
			ifCancel: { .cancel })
	}
}

// MARK: -  CustomZip (ErrorType: Semigroup)

public func zip <A,B,Z> (_ a: A, _ b: B) -> Result<(A.ElementType,B.ElementType),Z> where A: ResultType, B: ResultType, A.ErrorType == Z, B.ErrorType == Z, Z: Error & Semigroup {
	return a.run(
		ifSuccess: { aValue in b.run(
			ifSuccess: { bValue in .success((aValue,bValue)) },
			ifFailure: { bError in .failure(bError) },
			ifCancel: { .cancel }) },
		ifFailure: { aError in b.run(
			ifSuccess: F.constant(.failure(aError)),
			ifFailure: { bError in .failure(aError <> bError)},
			ifCancel: { .cancel }) },
		ifCancel: { .cancel })
}

// MARK: Utility

extension ResultType {
	public func mapError<E>(_ transform: @escaping (ErrorType) -> E) -> Result<ElementType,E> {
		return run(
			ifSuccess: Result.success,
			ifFailure: Result.failure • transform,
			ifCancel: F.constant(Result.cancel))
	}

	public var toOptionalValue: ElementType? {
		return run(
			ifSuccess: F.identity,
			ifFailure: F.constant(nil),
			ifCancel: F.constant(nil))
	}

	public var toOptionalError: ErrorType? {
		return run(
			ifSuccess: F.constant(nil),
			ifFailure: F.identity,
			ifCancel: F.constant(nil))
	}

	public func ifCanceled(_ converted: @autoclosure () -> Result<ElementType,ErrorType>) -> Result<ElementType,ErrorType> {
		return run(
			ifSuccess: Result.success,
			ifFailure: Result.failure,
			ifCancel: converted)
	}
}<commit_msg>added fallback(to:) method to ResultType<commit_after>import Abstract

// MARK: - Definition

// sourcery: concrete = "Result"
// sourcery: context = "ErrorType"
// sourcery: contextRequiredProtocols = "Error"
// sourcery: map, flatMap, zip, <*>, lift, lift+, lift-, lift*, lift/, liftPrefix-
// sourcery: transformer1, transformer2, transformer3
public protocol ResultType: PureConstructible {
	associatedtype ErrorType: Error
	init(_ error: ErrorType)
	init()
	func run <A> (ifSuccess: (ElementType) -> A, ifFailure: (ErrorType) -> A, ifCancel: () -> A) -> A
}

// MARK: - Concrete

// sourcery: context
// sourcery: contextRequiredProtocols = "Error"
// sourcery: functorLaws, applicativeLaws, monadLaws
// sourcery: fixedContextForLawsAndTests = "AnyError"
// sourcery: fixedTypesForTests = "Int"
// sourcery: arbitrary
// sourcery: arbitraryAdditionalParameterForGeneric = "E"
// sourcery: arbitraryAdditionalGenericParameterProtocols = "Error & Arbitrary"
public enum Result<T,E>: ResultType where E: Error {
	public typealias ElementType = T
	public typealias ErrorType = E

	case success(T)
	case failure(E)
	case cancel

	public init(_ value: ElementType) {
		self = .success(value)
	}

	public init(_ error: ErrorType) {
		self = .failure(error)
	}

	public init() {
		self = .cancel
	}

	public func run<A>(ifSuccess: (T) -> A, ifFailure: (E) -> A, ifCancel: () -> A) -> A {
		switch self {
		case .success(let value):
			return ifSuccess(value)
		case .failure(let error):
			return ifFailure(error)
		case .cancel:
			return ifCancel()
		}
	}

	public func get() throws -> ElementType? {
		switch self {
		case .success(let value):
			return value
		case .failure(let error):
			throw error
		case .cancel:
			return nil
		}
	}
}

extension Result where T: Equatable, E: Equatable {
	public static func == (left: Result, right: Result) -> Bool {
		switch (left,right) {
		case (.success(let leftValue), .success(let rightValue)):
			return leftValue == rightValue
		case (.failure(let leftError), .failure(let rightError)):
			return leftError == rightError
		case (.cancel,.cancel):
			return true
		default:
			return false
		}
	}
}

// MARK: - Functor

extension ResultType {
	public func map <A> (_ transform: @escaping (ElementType) -> A) -> Result<A,ErrorType> {
		return run(
			ifSuccess: { .success(transform($0)) },
			ifFailure: { .failure($0) },
			ifCancel: { .cancel })
	}
}

// MARK: - Joined

extension ResultType where ElementType: ResultType, ElementType.ErrorType == ErrorType {
	public var joined: Result<ElementType.ElementType,ErrorType> {
		return run(
			ifSuccess: { $0.run(
				ifSuccess: { .success($0) },
				ifFailure: { .failure($0) },
				ifCancel: { .cancel }) },
			ifFailure: { .failure($0) },
			ifCancel: { .cancel })
	}
}

// MARK: -  CustomZip (ErrorType: Semigroup)

public func zip <A,B,Z> (_ a: A, _ b: B) -> Result<(A.ElementType,B.ElementType),Z> where A: ResultType, B: ResultType, A.ErrorType == Z, B.ErrorType == Z, Z: Error & Semigroup {
	return a.run(
		ifSuccess: { aValue in b.run(
			ifSuccess: { bValue in .success((aValue,bValue)) },
			ifFailure: { bError in .failure(bError) },
			ifCancel: { .cancel }) },
		ifFailure: { aError in b.run(
			ifSuccess: F.constant(.failure(aError)),
			ifFailure: { bError in .failure(aError <> bError)},
			ifCancel: { .cancel }) },
		ifCancel: { .cancel })
}

// MARK: Utility

extension ResultType {
	public func mapError<E>(_ transform: @escaping (ErrorType) -> E) -> Result<ElementType,E> {
		return run(
			ifSuccess: Result.success,
			ifFailure: Result.failure • transform,
			ifCancel: F.constant(Result.cancel))
	}

	public func fallback(to defaultValue: ElementType) -> Result<ElementType,ErrorType> {
		return run(
			ifSuccess: Result<ElementType,ErrorType>.success,
			ifFailure: F.constant(Result<ElementType,ErrorType>.success(defaultValue)),
			ifCancel: F.constant(Result<ElementType,ErrorType>.success(defaultValue)))
	}

	public var toOptionalValue: ElementType? {
		return run(
			ifSuccess: F.identity,
			ifFailure: F.constant(nil),
			ifCancel: F.constant(nil))
	}

	public var toOptionalError: ErrorType? {
		return run(
			ifSuccess: F.constant(nil),
			ifFailure: F.identity,
			ifCancel: F.constant(nil))
	}

	public func ifCanceled(_ converted: @autoclosure () -> Result<ElementType,ErrorType>) -> Result<ElementType,ErrorType> {
		return run(
			ifSuccess: Result.success,
			ifFailure: Result.failure,
			ifCancel: converted)
	}
}
{'fraction_non_alphanumeric': 0.1423910510370543, 'fraction_numerical': 0.0020974131903985084, 'mean_word_length': 3.8989726027397262, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 70, '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': '480743', 'n_tokens_mistral': 3092, 'n_tokens_neox': 2797, 'n_words': 750}