3

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

DreamingOfSleep
  • 1,208
  • 1
  • 11
  • 23
  • What's the compiler error? Please [edit](https://stackoverflow.com/posts/72338779/edit) the question by adding the actual error. – Mark Seemann May 22 '22 at 16:28

1 Answers1

1

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.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
  • 1
    Thanks, that was exactly what I needed. Finding it hard to navigate this library, but enjoying the elegance it gives. As for your comment about `if/else`, you're right in the noddy example I showed. My real code is more complex and does pass around immutable values (or will when I've finished it). I was just trying to keep the sample code short so it was easy to see my question. Thanks very much – DreamingOfSleep May 22 '22 at 17:21