- class TemplatePart<INPUT, VALUE>
- {
- public VALUE Value { get; private set; }
- public INPUT Rest { get; private set; }
- public Action<VALUE> Ctor { get; private set; }
- public TemplatePart(VALUE value, INPUT rest, Action<VALUE> ctor) { Value = value; Rest = rest; Ctor = ctor; Ctor(Value); }
- }
- class TemplateEngine<INPUT, VALUE>
- {
- public Func<INPUT, TemplatePart<INPUT, VALUE>> F { get; private set; }
- public TemplateEngine(Func<INPUT, TemplatePart<INPUT, VALUE>> f) { F = f; }
- public static TemplateEngine<INPUT, VALUE> operator |(TemplateEngine<INPUT, VALUE> A, TemplateEngine<INPUT, VALUE> B)
- {
- return new TemplateEngine<INPUT, VALUE>((x) => A.F(x) ?? B.F(x));
- }
- public static TemplateEngine<INPUT, VALUE> operator -(TemplateEngine<INPUT, VALUE> A, TemplateEngine<INPUT, VALUE> B)
- {
- return new TemplateEngine<INPUT, VALUE>((x) => B.F(A.F(x).Rest));
- }
- public static TemplateEngine<INPUT, VALUE[]> operator +(TemplateEngine<INPUT, VALUE> A, TemplateEngine<INPUT, VALUE> B)
- {
- return new TemplateEngine<INPUT, VALUE[]>((x) =>
- {
- var a = A.F(x);
- var b = B.F(a.Rest);
- return new TemplatePart<INPUT, VALUE[]>(new VALUE[2] { a.Value, b.Value }, b.Rest, (y) =>
- {
- //no constructor needed
- });
- });
- }
- public static TemplateEngine<INPUT, VALUE[]> operator +(TemplateEngine<INPUT, VALUE[]> A, TemplateEngine<INPUT, VALUE> B)
- {
- return new TemplateEngine<INPUT, VALUE[]>((x) =>
- {
- var a = A.F(x);
- var b = B.F(a.Rest);
- return new TemplatePart<INPUT, VALUE[]>(a.Value.Concat(new[] {b.Value}).ToArray(), b.Rest, (y) =>
- {
- //no constructor needed
- });
- });
- }
- public static TemplateEngine<INPUT, VALUE[]> operator +(TemplateEngine<INPUT, VALUE> A, TemplateEngine<INPUT, VALUE[]> B)
- {
- return new TemplateEngine<INPUT, VALUE[]>((x) =>
- {
- var a = A.F(x);
- var b = B.F(a.Rest);
- return new TemplatePart<INPUT, VALUE[]>((new[] {a.Value}).Concat(b.Value).ToArray(), b.Rest, (y) =>
- {
- //no constructor needed
- });
- });
- }
- }