 }
 
 
-// MARK: - Free functions
+// MARK: - Either : CustomDebugStringConvertible
 
-/// If `left` is `Either.Right`, extracts its value and passes it to `transform`, returning the result; otherwise transforms `either` into the return type.
-///
-/// This is the bind or flat map operator, and is useful for chaining computations taking some parameter and returning an `Either`.
-public func >>- <T, U, V> (either: Either<T, U>, transform: (U) -> Either<T, V>) -> Either<T, V> {
-	return either.flatMap(transform)
+extension Either: CustomDebugStringConvertible {
+	public var debugDescription: String {
+		return either(
+			ifLeft: { ".Left(\(String(reflecting: $0)))" },
+			ifRight: { ".Right(\(String(reflecting: $0)))" })
+	}
 }
 
+// MARK: - Methods
+
+extension Either {
+	/// Maps `Right` values with `transform`, and re-wraps `Left` values.
+	public func map<V>(_ transform: (U) -> V) -> Either<T, V> {
+		return flatMap { .right(transform($0)) }
+	}
+	
+	/// Returns the result of applying `transform` to `Right` values, or re-wrapping `Left` values.
+	public func flatMap<V>(_ transform: (U) -> Either<T, V>) -> Either<T, V> {
+		return either(
+			ifLeft: Either<T, V>.left,
+			ifRight: transform)
+	}
+	
+	/// Maps `Left` values with `transform`, and re-wraps `Right` values.
+	public func mapLeft<V>(_ transform: (T) -> V) -> Either<V, U> {
+		return flatMapLeft { .left(transform($0)) }
+	}
+	
+	/// Returns the result of applying `transform` to `Left` values, or re-wrapping `Right` values.
+	public func flatMapLeft<V>(_ transform: (T) -> Either<V, U>) -> Either<V, U> {
+		return either(
+			ifLeft: transform,
+			ifRight: Either<V, U>.right)
+	}
+}
 
 // MARK: - Operators
 

			return try ifRight(x)
		}
	}

	/// Maps `Right` values with `transform`, and re-wraps `Left` values.
	public func map<V>(_ transform: (U) -> V) -> Either<T, V> {
		return flatMap { .right(transform($0)) }
	}

	/// Returns the result of applying `transform` to `Right` values, or re-wrapping `Left` values.
	public func flatMap<V>(_ transform: (U) -> Either<T, V>) -> Either<T, V> {
		return either(
			ifLeft: Either<T, V>.left,
			ifRight: transform)
	}

	/// Maps `Left` values with `transform`, and re-wraps `Right` values.
	public func mapLeft<V>(_ transform: (T) -> V) -> Either<V, U> {
		return flatMapLeft { .left(transform($0)) }
	}

	/// Returns the result of applying `transform` to `Left` values, or re-wrapping `Right` values.
	public func flatMapLeft<V>(_ transform: (T) -> Either<V, U>) -> Either<V, U> {
		return either(
			ifLeft: transform,
			ifRight: Either<V, U>.right)
	}


	// MARK: CustomDebugStringConvertible

	public var debugDescription: String {
		return either(
			ifLeft: { ".Left(\(String(reflecting: $0)))" },
			ifRight: { ".Right(\(String(reflecting: $0)))" })
	}


	// MARK: CustomStringConvertible

	public var description: String {
		return either(
			ifLeft: { ".Left(\($0))"},


infix operator >>- : Bind

/// If `left` is `Either.Right`, extracts its value and passes it to `transform`, returning the result; otherwise transforms `either` into the return type.
///
/// This is the bind or flat map operator, and is useful for chaining computations taking some parameter and returning an `Either`.
public func >>- <T, U, V> (either: Either<T, U>, transform: (U) -> Either<T, V>) -> Either<T, V> {
	return either.flatMap(transform)
}


// MARK: - Imports

import Prelude
