This is a follow-up question to a similar one I asked about binding monads that return different types. I realised after getting a clear answer that I hadn't asked the full question. Rather than amend that question (which does stand on its own so is worth leaving), Mark Seemann (who answered) suggested I ask this as a new question, so here goes.
For simplicity, I'm presenting a use-case that isn't really realistic (eg role-checking could be done differently, etc), but I'm trying not to confuse the question, so please bear with me.
Suppose I want to write a method that accepts an int
, and needs to...
- Check the authed used is in the appropriate role to make the request
- Check the Id corresponds to a customer in the database
- Check if the customer is active
If we get through all that lot, we return the customer, if not we return an error message. All methods are async
.
I have the following (simplified) methods...
async static Task<Either<string, int>> CheckUser(int id) {
// Check the authed user is in the right role, etc. For simplicity, we'll just branch on the id
// Simulate some async work
await Task.Delay(0);
if (id < 0) {
return "Invalid";
}
return id;
}
async static Task<Option<Customer>> Exists(int id) {
// Check the customer id refers to a real customer. Simulate some async work
await Task.Delay(0);
return id < 10 ? None : new Customer(id, "Jim Spriggs");
}
async static Task<Either<string, Customer>> IsActive(Customer c) {
// Simulate some async work
await Task.Delay(0);
if (c.Id % 2 == 0) {
return "Inactive";
}
return c;
}
record Customer(int Id, string Name);
I would like to bind these together as follows (in reality I would be doing more than writing the results to the console, but you get the idea)...
await CheckUser(31)
.Bind(async id => (await Exists(id)).ToEither("No such customer"))
.Bind(IsActive)
.Match(n => Console.WriteLine($"Success: {n}"), ex => Console.WriteLine($"Ex: {ex}"));
However, I get a compiler error on the id
parameter to Exists
on the 2nd line... "CS1503 Argument 1: cannot convert from 'LanguageExt.Either<string, int>' to 'int'"
I tried it with and without the await/async
keywords, but still couldn't get it to compile. I'm not sure if I need to add them in the lambdas or not.
Anyone able to explain how I do this? Thanks