Sorry if this is a dumb question, but I'm struggling with Language-Ext, and can't seem to find a neat way to do this.
In non-functional code, I could do something like this...
async Task DoFerretStuff(string id) {
Ferret? ferret = await ctx.Ferrets.FirstOrDefaultAsync(f => f.id == id);
if (ferret == null) {
// Do whatever needs doing when we can't find the ferret
} else {
// Do ferret stuff
}
}
I'm trying to do this in a more functional way, and assumed I would be able to do something like this...
async Task<Unit> DoFerretStuff(string id) =>
new Option<Ferret>(await ctx.Ferrets.FirstOrDefaultAsync(f => f.Id == id))
.Match(ferret => {
// Do ferret stuff
return unit;
},
() => {
// Do whatever needs doing when we can't find the ferret
return unit;
});
However, this gives a compiler error on the first line...
cannot convert from 'Ferret' to 'System.Collections.Generic.IEnumerable'
I don't understand why, as I thought the idea was that you could pass a (possibly null) object into the constructor for Option<T> and it would give either a Some<T> or a None<T>.
Please can someone explain how I should do this sort of thing in a functional way.
Thanks
The Option constructor takes an IEnumerable<A> as argument, which explains the compiler error.
Try the static Prelude.Optional function instead. One of those overloads takes a nullable value and converts it to Option<A>.
All that said, if you want to immediately Match on it afterwards to perform another side effect, then what are you gaining, compared to if/else?
FP would typically involve passing an immutable value (such as Option<Ferret>) to a pure function. The value can come from an impure action, such as ctx.Ferrets.FirstOrDefaultAsync, but it could also just be a value created on the spot. A pure function wouldn't care.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With