Last active
November 23, 2020 04:15
-
-
Save hez2010/e0f26c34500611761814c66dbd3211e1 to your computer and use it in GitHub Desktop.
Nat Emulation in C#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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