There is an operation on Result that isn't expressible by chaining maps and mapErrors, and it should probably be included with a stdlib Result:
extension Result {
func fold<C>(ifSuccess: (Value) -> C, ifFailure: (Error) -> C) -> C {
switch self {
case let .success(value): return ifSuccess(value)
case let .failure(error): return ifFailure(error)
}
}
}
This allows you to fold either case of a result into a single value. If you happen to use C = Result<NewValue, NewError> then you are recovering what you are looking for: the ability to simultaneously transform the value and error into a new result.
The fold name can be bikeshedded. Note that this function is the corresponding version of doing optional.map(f) ?? default in the optional world.