 
 import Swift
 
+public protocol ResultProtocol {
+	associatedtype Wrapped;
+	
+	var isSuccess: Bool { get }
+	var isFailure: Bool { get }
+
+	var value: Wrapped? { get };
+	var error: Error? { get };
+	
+	init (_ value: Wrapped);
+	init (_ error: Error);
+}
+
+public protocol ResultProtocolExtra: ResultProtocol {
+	init <R> (_ other: R) where R: ResultProtocol, R.Wrapped == Wrapped;
+	init <R> (_ other: R) where R: ResultProtocolExtra, R.Wrapped == Wrapped;
+
+	func converted <R> () -> R where R: ResultProtocol, R.Wrapped == Wrapped;
+
+	func map <T> (_ block: (Wrapped) throws -> Result <T>) rethrows -> Result <T>;
+	func map <T> (_ block: (Wrapped) throws -> T) rethrows -> Result <T>;
+	func map <T> (_ block: (Wrapped) throws -> T, error errorValue: @autoclosure () -> T) rethrows -> T;
+	func map <T> (_ valueBlock: (Wrapped) throws -> T, error errorBlock: (Error) throws -> T) rethrows -> T;
+	
+	mutating func withMutableValue <T> (perform block: (inout Wrapped) throws -> T, error errorValue: T) rethrows -> T;
+}
+
+public extension ResultProtocol {
+	public var isSuccess: Bool {
+		return self.value != nil;
+	}
+	
+	public var isFailure: Bool {
+		return self.error != nil;
+	}
+}
+
+public extension ResultProtocolExtra {
+	public init <R> (_ other: R) where R: ResultProtocol, R.Wrapped == Wrapped {
+		if let value = other.value {
+			self.init (value);
+		} else if let error = other.error {
+			self.init (error);
+		} else {
+			fatalError ("\(other) has invalid state (both value and error are nil)");
+		}
+	}
+	
+	public init <R> (_ other: R) where R: ResultProtocolExtra, R.Wrapped == Wrapped {
+		self = other.map (Self.init, error:Self.init);
+	}
+	
+	public func converted <R> () -> R where R: ResultProtocol, R.Wrapped == Wrapped {
+		return self.map (R.init, error: R.init);
+	}
+
+	public func map <T> (_ block: (Wrapped) throws -> Result <T>) rethrows -> Result <T> {
+		return try self.map ({ try block ($0) }, error: { .failure ($0) });
+	}
+	
+	public func map <T> (_ block: (Wrapped) throws -> T) rethrows -> Result <T> {
+		return try self.map ({ .success (try block ($0)) }, error: { .failure ($0) });
+	}
+	
+	public func map <T> (_ block: (Wrapped) throws -> T, error errorValue: @autoclosure () -> T) rethrows -> T {
+		return try self.map ({ try block ($0) }, error: errorValue);
+	}
+}
+
 public enum Result <Wrapped> {
 	case success (Wrapped);
 	case failure (Error);
 }
 
-public extension Result {
+extension Result: ResultProtocol {
 	public var isSuccess: Bool {
 		guard case .success = self else {
 			return false;

	public init (_ error: Error) {
		self = .failure (error);
	}
	
	public func map <T> (_ block: (Wrapped) throws -> Result <T>) rethrows -> Result <T> {
		return try self.map ({ try block ($0) }, error: { .failure ($0) });
	}
	
	public func map <T> (_ block: (Wrapped) throws -> T) rethrows -> Result <T> {
		return try self.map ({ .success (try block ($0)) }, error: { .failure ($0) });
	}
	
	public func map <T> (_ block: (Wrapped) throws -> T, error errorValue: @autoclosure () -> T) rethrows -> T {
		return try self.map ({ try block ($0) }, error: errorValue);
	}
	
	public func map <T> (_ valueBlock: (Wrapped) throws -> T, error errorBlock: (Error) throws -> T) rethrows -> T {
		switch (self) {
		case .success (let wrapped):

			return try errorBlock (error);
		}
	}

	public mutating func withMutableValue <T> (perform block: (inout Wrapped) throws -> T, error errorValue: T) rethrows -> T {
		guard case .success (var value) = self else {
			return errorValue;
