using System.Diagnostics;
public static void Main()
var watch = new Stopwatch();
Console.WriteLine(default(Fib<Zero>));
Console.WriteLine(default(Fib<Succ<Zero>>));
Console.WriteLine(default(Fib<Succ<Succ<Zero>>>));
Console.WriteLine(default(Fib<Succ<Succ<Succ<Zero>>>>));
Console.WriteLine(default(Fib<Succ<Succ<Succ<Succ<Succ<Zero>>>>>>));
Console.WriteLine(default(Fib<Succ<Succ<Succ<Succ<Succ<Succ<Zero>>>>>>>));
Console.WriteLine(watch.Elapsed);
struct Succ<TPrev> : INumber where TPrev : INumber
public int Value => default(TPrev).Value + 1;
struct Prev<TSucc> : INumber where TSucc : INumber
public int Value => default(TSucc).Value -1;
struct Minus<TLeft, TRight> : INumber where TLeft : INumber where TRight : INumber
if (default(TRight).Value == 0)
return default(TLeft).Value;
return default(Minus<Prev<TLeft>, Prev<TRight>>).Value;
struct Fib<T> : INumber where T : INumber
if (default(T).Value == 0)
else if (default(T).Value == 1)
return default(Fib<Minus<T, Succ<Zero>>>).Value + default(Fib<Minus<T, Succ<Succ<Zero>>>>).Value;
public override string ToString() => Value.ToString();