Search code examples
c#functional-programminglanguage-ext

LanguageExt: How do I do the equivalent of Option<T>.Match with a [Union]?


I want to create a union that will act a bit like Option<T>, but that allows a 3-way state, rather than a 2-way state. The reason for this is to use it when loading data from a database.

If I were doing this with an Option<T>, I would do something like this...

Option<Person> jimOpt = Option<Person>.None;
Person jimOpt = await _appDbContext.People.FirstOrDefault(p => p.Id == 1);
jimOpt.Match(person => {
    Console.WriteLine("Jim was found");
  },
  () => {
    Console.WriteLine("No such Jim");
  });

However, this doesn't distinguish between when the data is still loading and when the person is not found. This means that while the data is loading, the Option is in the None state, which gives the wrong impression in the UI, as it looks (briefly) as if the data was not found.

My idea is to create a Union like this...

[Union]
public interface Loading<T> {
  Loading<T> NotLoaded(); // Initial state, data not loaded yet
  Loading<T> Loaded(T value); // Data loaded successfully
  Loading<T> NotFound(); // Data access complete, but entity not found
}

...and do something like above, but setting it to be NotLoaded<Person> whilst the data access is going, and then either Loaded<Person> or NotFound<Person> when the data access has completed.

The problem is that the generated Union doesn't seem to have anything to help me here. I thought the idea of the code generation was to take away a lot of this grunt work.

Do I need to implement Match, Map, etc myself, or did I miss something in the code generation?

Thanks.


Solution

  • Match is now generated for Union types. You can also use the c# switch expressions