Yes, this simple sample is equivalent to your answer. But, like @suyashsrijan already said, my purpose was chaining results (like Combine) and get, at the end, one success value. But Combine is Apples framework and it`s not open source. Personally I would love to see more usage of the result type and I think, this extension is a good step.
That looks reasonable at first glance, but when I think about it for a bit I can’t see the use for a Result<T, Never>, since it’s equivalent to a plain T. This is quite different from reactive and futures frameworks, where a Publisher/Promise/Signal<T, Never> is a useful and common thing.
I'd definitely like to see a replaceFailure(ofType: with:) method that replaces errors of a given type with a default value. I could also see a version replaceFailure(_: with:) which replaces a specific error with the given success value.
I agree. This was my first idea too. But instead of:
enum SomeError: Error { case network, case invalidData }
let result: Result<Data, SomeError> = .failure(.network)
result.replaceFailure(.network, with: NetworkFallback) // type?
.replaceFailure(.invalidData, with: DataFallback) // not possible
I would suggest:
func replaceFailure(_ transform: (Failure) -> Success) -> Result<Success, Never> {
switch self {
case let .success(success):
return .success(success)
case let .failure(failure):
return .success(transform(failure))
}
}
usage:
let result = Result<Data, SomeError>.failure(.network)
.replaceFailure { error in
switch (error) {
case .network: return NetworkFallback
case .invalidData: return DataFallback
}
Yes, this was the intention. The idea is safely get the/one value. Currently, you can get the same result by:
let result = Result<Data, SomeError>.failure(.network)
let data: Data
do {
data = try result.get()
} catch {
error // type is Error instead of SomeError
data = genericFallback
}
print(data)
(try? result.get()) ?? genericFallback // shorthand
But using the do/catch variant, the error is a type of Error instead of SomeError. There is no easy/short way to replace the error with different "fallbacks", depending on the specific error of the Failure without handling the general error.
With try/catch:
let data: Data
do {
data = try result.get()
} catch SomeError.network {
data = networkFallback
} catch SomeError. invalidData {
data = dataFallback
} catch {
error // type is Error
data = genericFallback
}