         }
     }
 }
+
+extension Result: ResultProtocol {}

        case .fulfilled(let r):
            do    { return try .fulfilled( body(r) ) }
            catch { return     .rejected( error   ) }
        }
    }
}


import Foundation

// Abstract to a protocol for collection extensions
public protocol ResultProtocol {
    associatedtype FulfilledValue
    // SOMEDAY: make then return a ResultProtocol
    func then<NewFulfilledValue>( execute body: (FulfilledValue) throws -> NewFulfilledValue )  -> Result<NewFulfilledValue>
    func getOrThrow() throws -> FulfilledValue
    func recover(execute body: (Error) throws -> FulfilledValue) -> Self
    func `catch`( execute body: (Error) throws -> Void) rethrows -> Self
    
    func tap( execute body: (Self) -> Void ) -> Self
    func always( execute body: () -> Void ) -> Self
    var errorOrNil: Error? {get}
}

public enum Result<FulfilledValueParameter> {
    public typealias FulfilledValue = FulfilledValueParameter
    case fulfilled(FulfilledValue)
    case rejected(Error)
}
