Skip to content

Instantly share code, notes, and snippets.

@Kazark
Last active October 25, 2019 01:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kazark/8ad3a77674b93219725c5005962a4e40 to your computer and use it in GitHub Desktop.
Save Kazark/8ad3a77674b93219725c5005962a4e40 to your computer and use it in GitHub Desktop.
Maybe monad encoding in C#
class Nothing : Exception {}
public static class Maybe {
public static void Nothing() => throw new Nothing();
public static void Guard(bool cond) { if (!cond) Nothing(); }
public static void GuardNot(bool cond) { if (cond) Nothing(); }
}
public static class TryParse {
public static UInt32 UInt32(string x) {
UInt32 parsed;
Maybe.Guard(System.UInt32.TryParse(x, out parsed));
return parsed;
}
}
public static class Status {
static Tuple<char,string> FirstCharAndRest(string x) {
Maybe.Guard(x.Length > 0);
return Tuple.Create(x[0], x.Substring(1, x.Length-1));
}
static string TruncateAt(char c, string x) {
var index = x.IndexOf(c);
Maybe.Guard(index >= 0);
return index > 0 ? x.Substring(0, index) : "";
}
static Tuple<string,string> SplitInTwo(char c, string x) {
var xs = x.Split(c);
Maybe.Guard(xs.Length == 2);
return Tuple.Create(xs[0], xs[1]);
}
public static Tuple<UInt32,UInt32> Parse(string s) {
Maybe.GuardNot(s == null);
var firstCharAndRest = FirstCharAndRest(s);
Maybe.Guard(firstCharAndRest.Item1 == '[');
var xOfY = TruncateAt(']', firstCharAndRest.Item2);
var xAndY = SplitInTwo('/', xOfY);
var x = TryParse.UInt32(xAndY.Item1);
var y = TryParse.UInt32(xAndY.Item2);
return Tuple.Create(x, y);
}
}
void Main()
{
try {
var x = Status.Parse("[3/32] Monads!!");
Console.WriteLine($"{x.Item1} of {x.Item2}");
}
catch (Nothing) {
Console.WriteLine("Unable to parse.");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment