Skip to content

Instantly share code, notes, and snippets.

@arturaz
Created September 22, 2013 10:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arturaz/6658547 to your computer and use it in GitHub Desktop.
Save arturaz/6658547 to your computer and use it in GitHub Desktop.
Simple ADT matcher in C#
using System;
namespace Utils.Match {
public interface IMatcher<in Base, Return> where Base : class {
IMatcher<Base, Return> when<T>(Func<T, Return> onMatch)
where T : class, Base;
Return get();
Return getOrElse(Func<Return> elseFunc);
}
public class MatchError : Exception {
public MatchError(string message) : base(message) {}
}
public class Matcher<Base, Return> : IMatcher<Base, Return>
where Base : class {
private readonly Base subject;
public Matcher(Base subject) {
this.subject = subject;
}
public IMatcher<Base, Return> when<T>(Func<T, Return> onMatch)
where T : class, Base {
var casted = subject as T;
if (casted != null)
return new SuccessfulMatcher<Base, Return>(onMatch.Invoke(casted));
return this;
}
public Return get() {
throw new MatchError(string.Format(
"Subject {0} of type {1} couldn't be matched!", subject, typeof(Base)
));
}
public Return getOrElse(Func<Return> elseFunc) { return elseFunc.Invoke(); }
}
public class SuccessfulMatcher<Base, Return> : IMatcher<Base, Return>
where Base : class {
private readonly Return result;
public SuccessfulMatcher(Return result) {
this.result = result;
}
public IMatcher<Base, Return> when<T>(Func<T, Return> onMatch)
where T : class, Base { return this; }
public Return get() { return result; }
public Return getOrElse(Func<Return> elseFunc) { return get(); }
}
public class MatcherBuilder<T> where T : class {
private readonly T subject;
public MatcherBuilder(T subject) {
this.subject = subject;
}
public IMatcher<T, Return> returning<Return>() {
return new Matcher<T, Return>(subject);
}
}
public static class Match {
public static MatcherBuilder<T> match<T>(this T subject)
where T : class { return new MatcherBuilder<T>(subject); }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment