public static void Main()
.Map(Add.Map(Increment.Map(Halve)));
.Bind(AddString("Hello"))
public static Func<int,Func<int,int>> Add =
public static Func<int,int> Increment =
public static Func<int,int> Halve = x => x / 2;
public static Func<string,ValueTuple<int>?> Parse =
s => int.TryParse(s, out var x) ? x.Pure() : null;
public static Func<string,Func<int,ValueTuple<int>?>> AddString =
s => x => int.TryParse(s, out var y) ? (x + y).Pure() : null;
public static Func<int,Func<int,ValueTuple<int>?>> Divide =
x => y => x != 0 ? (y / x).Pure() : null;
public static class FuncExt
public static T Id<T>(T x) => x;
public static Func<S,T> Const<S,T>(T x) =>
public static Func<R,T> Map<R,S,T>(this Func<S,T> f, Func<R,S> g) =>
public static Func<S,T> Pure<S,T>(this T t) =>
public static class MaybeExt
public static ValueTuple<T>? Pure<T>(this T x) => new ValueTuple<T>(x);
public static ValueTuple<T>? Map<S,T>(this ValueTuple<S>? x, Func<S,T> f) =>
x.Maybe(null, y => f(y).Pure());
public static ValueTuple<T>? Join<T>(this ValueTuple<ValueTuple<T>?>? x) =>
public static ValueTuple<T>? Bind<S,T>(this ValueTuple<S>? x, Func<S,ValueTuple<T>?> f) =>
public static ValueTuple<T>? Apply<S,T>(this ValueTuple<Func<S,T>>? x, ValueTuple<S>? y) =>
public static S Maybe<S,T>(this ValueTuple<T>? x, S y, Func<T,S> f) => x switch
ValueTuple<T> v => f(v.Item1)
public static string GetString<T>(this ValueTuple<T>? x) =>
x.Maybe("Nothing", y => $"Just {y}");