Maybe Delegate

CSharp · Console

/Program.cs

using System;

public delegate T IMaybe<out T>();

public static class Maybe
{
	public static IMaybe<T> Return<T>(T x)
	{
		return () => x;
	}

	public static IMaybe<T> Nothing<T>()
	{
		return () =>
		{
			throw new InvalidOperationException("Нельзя получить значение");
		}

		;
	}

	public static IMaybe<TResult> Bind<TArg, TResult>(this IMaybe<TArg> maybe, Func<TArg, IMaybe<TResult>> func)
	{
		return () => func(maybe())();
	}

	public static IMaybe<TResult> Select<TArg, TResult>(this IMaybe<TArg> maybe, Func<TArg, TResult> func)
	{
		return maybe.Bind(value => Return(func(value)));
	}

	public static IMaybe<T> Where<T>(this IMaybe<T> maybe, Func<T, bool> predicate)
	{
		return maybe.Bind(x => predicate(x) ? Return(x) : Nothing<T>());
	}

	public static IMaybe<TC> SelectMany<TA, TB, TC>(this IMaybe<TA> ma, Func<TA, IMaybe<TB>> maybeSelector, Func<TA, TB, TC> resultSelector)
	{
		return ma.Bind(a => maybeSelector(a).Select(b => resultSelector(a, b)));
	}
}

public class Program
{
	public static void Main()
	{
		try
		{
			var one = Maybe.Return(1);
			var nothing = Maybe.Nothing<int>();
			var nothing2 =
				from ax in one
				from ay in nothing
				select ax + ay;
			
			var two = one.Where(z => z > 0).Select(z => z + 1);
			Console.WriteLine(one());
			Console.WriteLine(two());
			Console.WriteLine(nothing2());
		}
		catch (Exception e)
		{
			Console.WriteLine(e);
		}
	}
}
;