using System.Collections.Generic;
public abstract class Maybe<T>
public Maybe<T1> Map<T1>(Func<T, T1> f) =>
None<T>() => new None<T1>(),
Some<T>(var v) => new Some<T1>(f(v)),
_ => throw new NotImplementedException(),
public class None<T> : Maybe<T>
public void Deconstruct() { }
public class Some<T> : Maybe<T>
private readonly T value;
public Some(T value) => this.value = value;
public void Deconstruct(out T value) => value = this.value;
public static class FunctionalExtensions
public static Maybe<T> FirstOrNone<T>(this List<T> @source, Func<T, bool> predicate)
var firstOrDefault = @source.FirstOrDefault(predicate);
if (firstOrDefault != null)
return new Some<T>(firstOrDefault);
public static void Main()
string result = new None<int>()
None<int>() => "nothing",
Some<int>(var x) => x.ToString(),
_ => throw new NotImplementedException(),
Console.WriteLine(result);
public class MockClientRepository
List<Client> clients = new List<Client>{
new Client{Id=1, Name="Jim"},
new Client{Id=2, Name="John"}
public Maybe<Client> GetById(int id) => clients.FirstOrNone(x => x.Id == id);
public int Id { get; set; }
public string Name { get; set; }
public int EmployeeId { get; set; }