Hi all,
I have encountered an issue with the following code that fails to compile:
let message = Result { try decoder.decode(ConsumerMessage.self, from: payload) }
.flatMap { (msg: ConsumerMessage) async in
let analysed = await wa.doesContainViolentOrHarmfulMeaning(keywords: msg.interests)
if (analysed) {
return Result.failure(ConsumerError.harmfulOrViolentInterests("Interests contain harmful or violent meaning"))
} else {
return await redis.sadd(msg.interests, to: RedisKey(id)).get() != 0 ? Result.failure(ConsumerError.storeInterestsFailed("Failed to publish the interests")) : Result.success("Interests have been successfully published")
}
}
The compiler raises the following complaints:
Cannot pass function of type '(ConsumerMessage) async -> Result<_, any Error>' to parameter expecting synchronous function type
Generic parameter 'NewSuccess' could not be inferred
How can I execute asynchronous code within the flatMap closure? I couldn't find an async variant in the documentation at https://developer.apple.com/documentation/swift/result/flatmap(_:) .
Best regards
Jon_Shier
(Jon Shier)
2
You cannot. As you found, such a variant doesn't exist, so you'll need to add it yourself.
2 Likes
sveinhal
(Svein Halvor Halvorsen)
3
Something like this will work:
extension Result {
func flatMap<NewSuccess>(_ transform: (Success) async -> Result<NewSuccess, Failure>) async -> Result<NewSuccess, Failure> {
switch self {
case .success(let success):
return await transform(success)
case .failure(let failure):
return .failure(failure)
}
}
}
But note that you'll need to change your first line to
let message = await Result { try decoder.decode(ConsumerMessage.self, from: payload) }
// ^^^^^
.flatMap { ... }
sam2000
(sam)
4
Is there any reason why it is not part of Swift? With the introduction of "async throws", this seems to be a natural addition to the result type. It seems trivial to add this and the related "map", "get" and and async counter part to the Result init that takes an async throwing closure etc. I wonder if there is a good reason for not having these things as part of Swift?
1 Like