Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using Environment = System.Collections.Generic.Dictionary<int, string>;
- interface IFormlet<T>
- {
- string Render();
- T Evaluate(Environment env);
- }
- class Input<T> : IFormlet<T>
- {
- readonly int id;
- readonly Func<string, T> parser;
- public Input(int id, Func<string, T> parser)
- {
- this.id = id;
- this.parser = parser;
- }
- public string Render()
- {
- return "Input #{0} lol".Format(this.id);
- }
- public T Evaluate(Environment env)
- {
- return this.parser(env[this.id]);
- }
- }
- class Composition<T1, T2, TR> : IFormlet<TR>
- {
- readonly IFormlet<T1> f1;
- readonly IFormlet<T2> f2;
- readonly Func<T1, T2, TR> evaluator;
- public Composition(IFormlet<T1> f1, IFormlet<T2> f2, Func<T1, T2, TR> evaluator)
- {
- this.f1 = f1;
- this.f2 = f2;
- this.evaluator = evaluator;
- }
- public string Render()
- {
- return f1.Render() + "; " + f2.Render();
- }
- public TR Evaluate(Dictionary<int, string> env)
- {
- return evaluator(f1.Evaluate(env), f2.Evaluate(env));
- }
- }
- class Composition2<TSource, TIntermediate, TResult> : IFormlet<TResult>
- {
- readonly IFormlet<TSource> f1;
- readonly Func<TSource, IFormlet<TIntermediate>> collectionSelector;
- readonly Func<TSource, TIntermediate, TResult> resultSelector;
- public Composition2(
- IFormlet<TSource> f1,
- Func<TSource, IFormlet<TIntermediate>> collectionSelector,
- Func<TSource, TIntermediate, TResult> resultSelector)
- {
- this.f1 = f1;
- this.collectionSelector = collectionSelector;
- this.resultSelector = resultSelector;
- }
- public string Render()
- {
- return f1.Render(); // can't do anything more!
- }
- public TResult Evaluate(Dictionary<int, string> env)
- {
- var r1 = f1.Evaluate(env);
- // Only here we get the second IFormlet,
- // only after we calculated r1.
- var f2 = collectionSelector(r1);
- var r2 = f2.Evaluate(env);
- return resultSelector(r1, r2);
- }
- }
- static class Extensions
- {
- public static string Format(this string format, params object[] args)
- {
- return String.Format(format, args);
- }
- public static IFormlet<TR> Join<T1, T2, TKey, TR>(
- this IFormlet<T1> f1,
- IFormlet<T2> f2,
- Func<T1, TKey> selector1,
- Func<T2, TKey> selector2,
- Func<T1, T2, TR> resultSelector)
- {
- Console.WriteLine("Composing '{0}' + '{1}'".Format((object)f1.Render(), f2.Render()));
- return new Composition<T1, T2, TR>(f1, f2, resultSelector);
- }
- public static IFormlet<TResult> SelectMany<TSource, TIntermediate, TResult>(
- this IFormlet<TSource> f1,
- Func<TSource, IFormlet<TIntermediate>> collectionSelector,
- Func<TSource, TIntermediate, TResult> resultSelector)
- {
- return new Composition2<TSource, TIntermediate, TResult>(f1, collectionSelector, resultSelector);
- }
- }
- public class JustTest1
- {
- public static void Main()
- {
- var env = new Environment() { { 1, "11" }, { 2, "22" }, { 3, "33" } };
- var composed =
- from x in new Input<int>(1, s => int.Parse(s))
- join y in new Input<int>(2, s => int.Parse(s)) on 1 equals 1
- join z in new Input<int>(3, s => int.Parse(s)) on 1 equals 1
- select "Result: {0}, {1}, {2}".Format(x, y, z);
- Console.WriteLine(composed.Render());
- Console.WriteLine(composed.Evaluate(env));
- var composed2 =
- from x in new Input<int>(1, s => int.Parse(s))
- from y in new Input<int>(2, s => int.Parse(s))
- from z in new Input<int>(3, s => int.Parse(s))
- select "Result: {0}, {1}, {2}".Format(x, y, z);
- Console.WriteLine(composed2.Render());
- Console.WriteLine(composed2.Evaluate(env));
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement