Ejemplo n.º 1
0
        public static ISimpleArrow Comb(ISimpleArrow a1, ISimpleArrow a2)
        {
            // Get the three generic types
            Type t1 = a1.a;
            Type t2 = a1.b;
            Type t3 = a2.b;

            // Create types for the combined function and the two source functions
            Type funcType   = typeof(Func <,>).MakeGenericType(t1, t3);
            Type a1FuncType = typeof(Func <,>).MakeGenericType(t1, t2);
            Type a2FuncType = typeof(Func <,>).MakeGenericType(t2, t3);

            // Get the types of the two arrows
            Type a1Type = a1.GetType();
            Type a2Type = a2.GetType();

            // Get an arrow constructor, genericised
            Type[] arrowConstructorTypes = new Type[1];
            arrowConstructorTypes[0] = funcType;
            ConstructorInfo arrowConstructor = typeof(SimpleArrow <,>).MakeGenericType(t1, t3).GetConstructor(arrowConstructorTypes);

            // Get the two arrows' lambda functions (type safety is cast asunder from here on...)
            dynamic ar1 = a1;
            dynamic ar2 = a2;
            dynamic l1  = ar1.function;
            dynamic l2  = ar2.function;

            // Get a genericised version of the CombineLambdas function
            Type[] types2 = new Type[3];
            types2[0] = t1;
            types2[1] = t2;
            types2[2] = t3;
            MethodInfo combinator = typeof(LambdaCombinator).GetMethod("CombineLambdas");

            combinator = combinator.MakeGenericMethod(types2);

            // Invoke the genericised CombineLambdas function on the extracted lambda functions
            dynamic[] combineArgs = new dynamic[2];
            combineArgs[0] = l1;
            combineArgs[1] = l2;
            dynamic combinedFunc = combinator.Invoke(null, combineArgs);

            // Invoke the genericised arrow constructor on the result of the CombineLambdas function
            dynamic[] parameters = new dynamic[1];
            parameters[0] = combinedFunc;
            dynamic result = arrowConstructor.Invoke(parameters);

            return(result);
        }
Ejemplo n.º 2
0
        public void LambdaCombinatorDemo()
        {
            // Combining with messy type parameterisation
            Func <int, int>    f1 = x => x * x;
            Func <int, string> f2 = x =>
            {
                if (x > 5)
                {
                    return("X^2 > 5!");
                }
                else
                {
                    return("X^2 < 5 :O");
                }
            };
            Func <int, string> combination = LambdaCombinator.CombineLambdas <int, int, string>(f1, f2);

            Console.WriteLine(combination(3));
            Console.WriteLine(combination(2));
            Console.WriteLine();

            // Nicer combination
            Console.WriteLine("Now trying it with a type-parameter-free combinator...");
            ISimpleArrow result = LambdaCombinator.Comb(new SimpleArrow <int, int>(f1), new SimpleArrow <int, string>(f2));
            SimpleArrow <int, string> arrowResult = (SimpleArrow <int, string>)result;

            Console.WriteLine(arrowResult.function.Invoke(3));

            // Combining in one line
            SimpleArrow <string, string> another       = new SimpleArrow <string, string>(x => x.Length.ToString());
            SimpleArrow <int, string>    anotherResult = (SimpleArrow <int, string>)(LambdaCombinator.Comb(
                                                                                         LambdaCombinator.Comb(
                                                                                             new SimpleArrow <int, int>(f1),
                                                                                             new SimpleArrow <int, string>(f2)),
                                                                                         another));

            Console.WriteLine(anotherResult.function.Invoke(3));

            // Combining in one line without downcasting (using only arrow interfaces now)
            ISimpleArrow thingy = LambdaCombinator.Comb(
                new SimpleArrow <int, string>(x => x.ToString()),
                new SimpleArrow <string, int>(x => x.Length)
                );

            Console.WriteLine(thingy.Invoke(1234));
        }