Skip to content

Instantly share code, notes, and snippets.

@hez2010
Last active November 23, 2020 04:15
Show Gist options
  • Save hez2010/e0f26c34500611761814c66dbd3211e1 to your computer and use it in GitHub Desktop.
Save hez2010/e0f26c34500611761814c66dbd3211e1 to your computer and use it in GitHub Desktop.
Nat Emulation in C#
using System;
namespace NatEmulation
{
public abstract record Nat()
{
public static Nat operator +(Nat left, Nat right) =>
left switch
{
Zero => right,
Succ(Nat x) => new Succ(x + right),
_ => throw new InvalidOperationException()
};
public static Nat operator -(Nat left, Nat right) =>
(left, right) switch
{
(Zero, _) or (_, Zero) => left,
(Succ(Nat x), Succ(Nat y)) => x - y,
_ => throw new InvalidOperationException()
};
public static Nat operator *(Nat left, Nat right) =>
(left, right) switch
{
(Zero, _) => left,
(Succ(Nat x), _) => right + x * right,
_ => throw new InvalidOperationException()
};
public static Nat operator /(Nat left, Nat right) =>
(left, right) switch
{
(Zero, _) => left,
_ => new Succ((left - right) / right)
};
public static implicit operator Nat(int i) => i switch
{
0 => new Zero(),
> 0 => new Succ(i - 1),
_ => throw new InvalidOperationException()
};
public static explicit operator int(Nat i) => i switch
{
Zero => 0,
Succ(Nat x) => 1 + (int)x,
_ => throw new InvalidOperationException()
};
}
public record Zero() : Nat;
public record Succ(Nat Value) : Nat;
public class Program
{
public static void Print(Nat value, string expr)
{
Console.WriteLine($"{expr} = {(int)value}, express: {value}");
}
public static void Main()
{
Nat n1 = 2;
Nat n2 = 6;
Print(n1 + n2, "n1 + n2");
Print(n2 - n1, "n2 - n1");
Print(n1 * n2, "n1 * n2");
Print(n2 / n1, "n2 / n1");
Console.WriteLine(n1 == n2 / 3);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment