Example #1
0
        public static RuleExprAst <V> SelectMany <T, U, V>(this RuleExprAst <T> expr, Expression <Func <T, RuleExprAst <U> > > selector, Expression <Func <T, U, V> > projector)
        {
            var context = Expression.Parameter(typeof(RuleExprContext), "context");
            var intermediateValueAndContext = Expression.Invoke(expr.Expression, context);
            var intermediateValue           = Expression.Field(intermediateValueAndContext, "Item1");
            var intermediateContext         = Expression.Field(intermediateValueAndContext, "Item2");
            var selectorResult           = Expression.Invoke(selector, intermediateValue);
            var selectorResultExpression = Expression.Property(selectorResult, "Expression");
            var finalValueAndContext     = Expression.Invoke(selectorResultExpression, intermediateContext);
            var finalValue     = Expression.Field(finalValueAndContext, "Item1");
            var finalContext   = Expression.Field(finalValueAndContext, "Item2");
            var projectedValue = Expression.Invoke(projector, intermediateValue, finalValue);

            var tupleConstructor = typeof(Tuple <V, RuleExprContext>).GetConstructor(new[] { typeof(V), typeof(RuleExprContext) });
            var returnTuple      = Expression.New(tupleConstructor, new Expression[] { projectedValue, finalContext });
            var toValueTupleInfo = typeof(TupleExtensions).GetMethodExt("ToValueTuple", new[] { typeof(Tuple <,>) });
            var toValueTuple     = toValueTupleInfo.MakeGenericMethod(typeof(V), typeof(RuleExprContext));
            var returnValueTuple = Expression.Call(null, toValueTuple, returnTuple);
            var resultFunc       = Expression.Lambda <RuleExpr <V> >(returnValueTuple, context);

            return(new RuleExprAst <V> {
                Expression = resultFunc
            });

            //return context =>
            //{
            //    var (a, context2) = expr(context);
            //    var (b, context3) = selector(a)(context2);
            //    return (projector(a, b), context3);
            //};
        }
Example #2
0
        public static RuleExprAst <Unit, RuleExprContext> Join <RuleExprContext>(this RuleExprAst <Unit, RuleExprContext> expr, RuleExprAst <Unit, RuleExprContext> exprNext)
        {
            var context = Expression.Parameter(typeof(RuleExprContext), "context");

            var valueOptionAndContextAVar = Expression.Variable(typeof((Option <Unit>, RuleExprContext)), "valueOptionAndContextAVar");
            var valueOptionAVar           = Expression.Variable(typeof(Option <Unit>), "valueOptionAVar");
            var contextAVar = Expression.Variable(typeof(RuleExprContext), "contextAVar");

            var functionImplementation =
                Expression.Block(
                    Expression.Assign(valueOptionAndContextAVar, Expression.Invoke(expr.Expression, context)),
                    Expression.Assign(valueOptionAVar, Expression.Field(valueOptionAndContextAVar, "Item1")),
                    Expression.Assign(contextAVar, Expression.Field(valueOptionAndContextAVar, "Item2")),
                    Expression.Condition(
                        Expression.Equal(Expression.Field(valueOptionAVar, "isSome"), Expression.Constant(true)),
                        Expression.Invoke(exprNext.Expression, contextAVar),
                        MkTuple <Option <Unit>, RuleExprContext>(
                            GetNoneValue <Unit>(),
                            contextAVar
                            )
                        )
                    );

            var functionBody =
                Expression.Block(
                    new[] { valueOptionAndContextAVar, valueOptionAVar, contextAVar },
                    functionImplementation
                    );

            var function = Expression.Lambda <RuleExpr <Unit, RuleExprContext> >(functionBody, context);

            return(new RuleExprAst <Unit, RuleExprContext> {
                Expression = function
            });
        }
Example #3
0
        public static RuleExprAst <T, RuleExprContext <Unit> > Lift <T>(this RuleExprAst <T, RuleExprContext <string> > sRuleExprAst, VoteMethod <T> vote)
        {
            var sRule = sRuleExprAst.ExceptionContext().Compile();
            var sKeys = sRuleExprAst.GetKeys();

            return(new RuleExprAst <T, RuleExprContext <Unit> >
            {
                Expression = mcontext => sRule.LiftImpl(vote, sKeys)(mcontext)
            });
        }
Example #4
0
        public static RuleExprAst <T, RuleExprContext> Where <T, RuleExprContext>(this RuleExprAst <T, RuleExprContext> expr, Expression <Func <T, bool> > predicate)
        {
            var context = Expression.Parameter(typeof(RuleExprContext), "context");

            var valueOptionAndContextAVar = Expression.Variable(typeof((Option <T>, RuleExprContext)), "valueOptionAndContextAVar");
            var valueOptionAVar           = Expression.Variable(typeof(Option <T>), "valueOptionAVar");
            var contextAVar = Expression.Variable(typeof(RuleExprContext), "contextAVar");

            var functionImplementation =
                Expression.Block(
                    Expression.Assign(valueOptionAndContextAVar, Expression.Invoke(expr.Expression, context)),
                    Expression.Assign(valueOptionAVar, Expression.Field(valueOptionAndContextAVar, "Item1")),
                    Expression.Assign(contextAVar, Expression.Field(valueOptionAndContextAVar, "Item2")),
                    MkTuple <Option <T>, RuleExprContext>(
                        Expression.Condition(
                            Expression.Equal(Expression.Field(valueOptionAVar, "isSome"), Expression.Constant(true)),
                            Expression.Condition(
                                Expression.Equal(Expression.Invoke(predicate, Expression.Field(valueOptionAVar, "value")), Expression.Constant(true)),
                                WrapSome <T>(Expression.Field(valueOptionAVar, "value")),
                                GetNoneValue <T>()
                                ),
                            GetNoneValue <T>()
                            ),
                        contextAVar
                        )
                    );

            var functionBody =
                Expression.Block(
                    new[] { valueOptionAndContextAVar, valueOptionAVar, contextAVar },
                    functionImplementation
                    );

            var function = Expression.Lambda <RuleExpr <T, RuleExprContext> >(functionBody, context);

            return(new RuleExprAst <T, RuleExprContext> {
                Expression = function
            });

            //  return context =>
            //  {
            //      var (a, context') = expr(context);
            //      return (predicate(a) ? Some(a) : None, context');
            //  }
        }
Example #5
0
        public static RuleExprAst <Unit, RuleExprContext> Apply <T, RuleExprContext>(this RuleExprAst <T, RuleExprContext> expr) where T : IRuleContextApplicable
        {
            var context = Expression.Parameter(typeof(RuleExprContext), "context");

            var valueOptionAndContextAVar = Expression.Variable(typeof((Option <T>, RuleExprContext)), "valueOptionAndContextAVar");
            var valueOptionAVar           = Expression.Variable(typeof(Option <T>), "valueOptionAVar");
            var contextAVar = Expression.Variable(typeof(RuleExprContext), "contextAVar");

            var functionImplementation =
                Expression.Block(
                    Expression.Assign(valueOptionAndContextAVar, Expression.Invoke(expr.Expression, context)),
                    Expression.Assign(valueOptionAVar, Expression.Field(valueOptionAndContextAVar, "Item1")),
                    Expression.Assign(contextAVar, Expression.Field(valueOptionAndContextAVar, "Item2")),
                    Expression.Condition(
                        Expression.Equal(Expression.Field(valueOptionAVar, "isSome"), Expression.Constant(true)),
                        MkTuple <Option <Unit>, RuleExprContext>(
                            WrapSome <Unit>(Expression.Constant(Unit.Value)),
                            Expression.Call(
                                Expression.Field(valueOptionAVar, "value"),
                                typeof(IRuleContextApplicable).GetMethod("ApplyTo").MakeGenericMethod(typeof(RuleExprContext)),
                                contextAVar
                                )
                            ),
                        MkTuple <Option <Unit>, RuleExprContext>(
                            GetNoneValue <Unit>(),
                            contextAVar
                            )
                        )
                    );

            var functionBody =
                Expression.Block(
                    new[] { valueOptionAndContextAVar, valueOptionAVar, contextAVar },
                    functionImplementation
                    );

            var function = Expression.Lambda <RuleExpr <Unit, RuleExprContext> >(functionBody, context);

            return(new RuleExprAst <Unit, RuleExprContext> {
                Expression = function
            });
        }
Example #6
0
        public static RuleExprAst <U> Select <T, U>(this RuleExprAst <T> expr, Expression <Func <T, U> > convert)
        {
            var context            = Expression.Parameter(typeof(RuleExprContext), "context");
            var valueAndNewContext = Expression.Invoke(expr.Expression, context);
            var value            = Expression.Field(valueAndNewContext, "Item1");
            var newContext       = Expression.Field(valueAndNewContext, "Item2");
            var convertedValue   = Expression.Invoke(convert, value);
            var returnTuple      = Expression.New(typeof(Tuple <U, RuleExprContext>).GetConstructor(new[] { typeof(U), typeof(RuleExprContext) }), new Expression[] { convertedValue, newContext });
            var toValueTupleInfo = typeof(TupleExtensions).GetMethodExt("ToValueTuple", new[] { typeof(Tuple <,>) });
            var toValueTuple     = toValueTupleInfo.MakeGenericMethod(typeof(U), typeof(RuleExprContext));
            var returnValueTuple = Expression.Call(null, toValueTuple, returnTuple);
            var resultFunc       = Expression.Lambda <RuleExpr <U> >(returnValueTuple, context);

            return(new RuleExprAst <U> {
                Expression = resultFunc
            });
            //return context =>
            //{
            //    var (a, context2) = expr(context);
            //    return (convert(a), context2);
            //};
        }
Example #7
0
        // Previously known as WithLogging
        public static RuleExprAst <T, RuleExprContext> LogContext <T, RuleExprContext>(this RuleExprAst <T, RuleExprContext> expr, string message)
        {
            var context = Expression.Parameter(typeof(RuleExprContext), "context");

            var valueOptionAndContextAVar = Expression.Variable(typeof((Option <T>, RuleExprContext)), "valueOptionAndContextAVar");
            var valueOptionAVar           = Expression.Variable(typeof(Option <T>), "valueOptionAVar");
            var contextAVar = Expression.Variable(typeof(RuleExprContext), "contextAVar");

            var m = typeof(RuleExprContext).GetMethod("WithLogging");
            var functionImplementation =
                Expression.Block(
                    Expression.Assign(valueOptionAndContextAVar, Expression.Invoke(expr.Expression, context)),
                    Expression.Assign(valueOptionAVar, Expression.Field(valueOptionAndContextAVar, "Item1")),
                    Expression.Assign(contextAVar, Expression.Field(valueOptionAndContextAVar, "Item2")),
                    MkTuple <Option <T>, RuleExprContext>(
                        valueOptionAVar,
                        //Expression.Convert(
                        Expression.Call(
                            contextAVar,
                            typeof(RuleExprContext).GetMethod("WithLogging"),
                            CreateLogEntry(
                                Expression.Constant(message),
                                context,
                                contextAVar,
                                Expression.Convert(valueOptionAVar, typeof(object))
                                )
                            )//,
                        //    typeof(RuleExprContext)
                        //)
                        )
                    );

            var functionBody =
                Expression.Block(
                    new[] { valueOptionAndContextAVar, valueOptionAVar, contextAVar },
                    functionImplementation
                    );

            var function = Expression.Lambda <RuleExpr <T, RuleExprContext> >(functionBody, context);

            return(new RuleExprAst <T, RuleExprContext> {
                Expression = function
            });
        }
Example #8
0
 public static RuleExprAst <Unit, RuleExprContext <Unit> > RejectIf <T>(this RuleExprAst <T, RuleExprContext <string> > expr, Expression <Func <T, bool> > predicate, string message)
 {
     return(expr.Where(predicate).Select(_ => FailUnit.Value).LogContext(message).Lift());
 }
Example #9
0
        public static RuleExprAst <Option <T>, RuleExprContext> ExceptionContext <T, RuleExprContext>(this RuleExprAst <T, RuleExprContext> expr)
        {
            var context = Expression.Parameter(typeof(RuleExprContext), "context");

            var valueOptionAndContextAVar = Expression.Variable(typeof((Option <T>, RuleExprContext)), "valueOptionAndContextAVar");
            var valueOptionAVar           = Expression.Variable(typeof(Option <T>), "valueOptionAVar");
            var contextAVar = Expression.Variable(typeof(RuleExprContext), "contextAVar");

            var functionImplementation =
                Expression.Block(
                    Expression.Assign(valueOptionAndContextAVar, Expression.Invoke(expr.Expression, context)),
                    Expression.Assign(valueOptionAVar, Expression.Field(valueOptionAndContextAVar, "Item1")),
                    Expression.Assign(contextAVar, Expression.Field(valueOptionAndContextAVar, "Item2")),
                    MkTuple <Option <Option <T> >, RuleExprContext>(
                        WrapSome <Option <T> >(valueOptionAVar),
                        contextAVar
                        )
                    );

            var functionBody =
                Expression.Block(
                    new[] { valueOptionAndContextAVar, valueOptionAVar, contextAVar },
                    functionImplementation
                    );

            var function = Expression.Lambda <RuleExpr <Option <T>, RuleExprContext> >(functionBody, context);

            return(new RuleExprAst <Option <T>, RuleExprContext> {
                Expression = function
            });
        }
Example #10
0
        public static RuleExprAst <IEnumerable <V>, RuleExprContext> SelectMany <T, U, V, RuleExprContext>(this RuleExprAst <T, RuleExprContext> expr, Expression <Func <T, IEnumerable <RuleExprAst <U, RuleExprContext> > > > selector, Expression <Func <T, IEnumerable <U>, IEnumerable <V> > > projector)
        {
            var context = Expression.Parameter(typeof(RuleExprContext), "context");

            var valueOptionAndContextAVar = Expression.Variable(typeof((Option <T>, RuleExprContext)), "valueOptionAndContextAVar");
            var valueOptionAVar           = Expression.Variable(typeof(Option <T>), "valueOptionAVar");
            var contextAVar = Expression.Variable(typeof(RuleExprContext), "contextAVar");

            var valueOptionAndContextBVar = Expression.Variable(typeof((Option <ImmutableList <U> >, RuleExprContext)), "valueOptionAndContextBVar");
            var valueOptionBVar           = Expression.Variable(typeof(Option <ImmutableList <U> >), "valueOptionBVar");
            var contextBVar = Expression.Variable(typeof(RuleExprContext), "contextBVar");

            var functionImplementation =
                Expression.Block(
                    Expression.Assign(valueOptionAndContextAVar, Expression.Invoke(expr.Expression, context)),
                    Expression.Assign(valueOptionAVar, Expression.Field(valueOptionAndContextAVar, "Item1")),
                    Expression.Assign(contextAVar, Expression.Field(valueOptionAndContextAVar, "Item2")),
                    Expression.Condition(
                        Expression.Equal(Expression.Field(valueOptionAVar, "isSome"), Expression.Constant(true)),
                        Expression.Block(
                            Expression.Assign(valueOptionAndContextBVar,
                                              Expression.Invoke(
                                                  Sequence <U, RuleExprContext>(Expression.Invoke(selector, Expression.Field(valueOptionAVar, "value"))),
                                                  contextAVar
                                                  )),
                            Expression.Assign(valueOptionBVar, Expression.Field(valueOptionAndContextBVar, "Item1")),
                            Expression.Assign(contextBVar, Expression.Field(valueOptionAndContextBVar, "Item2")),
                            Expression.Condition(
                                Expression.Equal(Expression.Field(valueOptionBVar, "isSome"), Expression.Constant(true)),
                                MkTuple <Option <IEnumerable <V> >, RuleExprContext>(
                                    WrapSome <IEnumerable <V> >(Expression.Invoke(projector, Expression.Field(valueOptionAVar, "value"), Expression.Field(valueOptionBVar, "value"))),
                                    contextBVar
                                    ),
                                MkTuple <Option <IEnumerable <V> >, RuleExprContext>(GetNoneValue <IEnumerable <V> >(), contextBVar)
                                )
                            ),
                        MkTuple <Option <IEnumerable <V> >, RuleExprContext>(GetNoneValue <IEnumerable <V> >(), contextAVar)
                        )
                    );

            var functionBody =
                Expression.Block(
                    new[] { valueOptionAndContextAVar, valueOptionAVar, contextAVar, valueOptionAndContextBVar, valueOptionBVar, contextBVar },
                    functionImplementation
                    );
            var function = Expression.Lambda <RuleExpr <IEnumerable <V>, RuleExprContext> >(functionBody, context);

            return(new RuleExprAst <IEnumerable <V>, RuleExprContext> {
                Expression = function
            });

            //return context =>
            //{
            //    var (a, context1) = expr(context0);
            //    var fs = selector(a);
            //    var (bs, contextn) = (sequence fs)(context1)      // sequence :: IEnumerable<RuleExprAst<U>> -> RuleExprAst<IEnumerable<U>>
            //    return (projector(a, bs), contextn);
            //};
        }
Example #11
0
        public static RuleExprAst <V, RuleExprContext> SelectMany <T, U, V, RuleExprContext>(this RuleExprAst <T, RuleExprContext> expr, Expression <Func <T, RuleExprAst <U, RuleExprContext> > > selector, Expression <Func <T, U, V> > projector)
        {
            var context = Expression.Parameter(typeof(RuleExprContext), "context");

            var valueOptionAndContextAVar = Expression.Variable(typeof((Option <T>, RuleExprContext)), "valueOptionAndContextAVar");
            var valueOptionAVar           = Expression.Variable(typeof(Option <T>), "valueOptionAVar");
            var contextAVar = Expression.Variable(typeof(RuleExprContext), "contextAVar");

            var valueOptionAndContextBVar = Expression.Variable(typeof((Option <U>, RuleExprContext)), "valueOptionAndContextBVar");
            var valueOptionBVar           = Expression.Variable(typeof(Option <U>), "valueOptionBVar");
            var contextBVar = Expression.Variable(typeof(RuleExprContext), "contextBVar");

            var functionImplementation =
                Expression.Block(
                    Expression.Assign(valueOptionAndContextAVar, Expression.Invoke(expr.Expression, context)),
                    Expression.Assign(valueOptionAVar, Expression.Field(valueOptionAndContextAVar, "Item1")),
                    Expression.Assign(contextAVar, Expression.Field(valueOptionAndContextAVar, "Item2")),
                    Expression.Condition(
                        Expression.Equal(Expression.Field(valueOptionAVar, "isSome"), Expression.Constant(true)),
                        Expression.Block(
                            Expression.Assign(valueOptionAndContextBVar,
                                              Expression.Invoke(
                                                  Expression.Property(Expression.Invoke(selector, Expression.Field(valueOptionAVar, "value")), "Expression"),
                                                  contextAVar
                                                  )),
                            Expression.Assign(valueOptionBVar, Expression.Field(valueOptionAndContextBVar, "Item1")),
                            Expression.Assign(contextBVar, Expression.Field(valueOptionAndContextBVar, "Item2")),
                            Expression.Condition(
                                Expression.Equal(Expression.Field(valueOptionBVar, "isSome"), Expression.Constant(true)),
                                MkTuple <Option <V>, RuleExprContext>(
                                    WrapSome <V>(Expression.Invoke(projector, Expression.Field(valueOptionAVar, "value"), Expression.Field(valueOptionBVar, "value"))),
                                    contextBVar
                                    ),
                                MkTuple <Option <V>, RuleExprContext>(GetNoneValue <V>(), contextBVar)
                                )
                            ),
                        MkTuple <Option <V>, RuleExprContext>(GetNoneValue <V>(), contextAVar)
                        )
                    );

            var functionBody =
                Expression.Block(
                    new[] { valueOptionAndContextAVar, valueOptionAVar, contextAVar, valueOptionAndContextBVar, valueOptionBVar, contextBVar },
                    functionImplementation
                    );
            var function = Expression.Lambda <RuleExpr <V, RuleExprContext> >(functionBody, context);

            return(new RuleExprAst <V, RuleExprContext> {
                Expression = function
            });

            //return context =>
            //{
            //    var (a, context2) = expr(context);
            //    var (b, context3) = selector(a)(context2);
            //    return (projector(a, b), context3);
            //};
        }
Example #12
0
 public static RuleExprAst <Unit, RuleExprContext <Unit> > Lift(this RuleExprAst <Amount, RuleExprContext <string> > sRuleExprAst)
 {
     return(sRuleExprAst.Lift(VoteMethods.MinValue).Apply());
 }
Example #13
0
 public static RuleExprAst <Unit, RuleExprContext <Unit> > Lift(this RuleExprAst <FailUnit, RuleExprContext <string> > sRuleExprAst)
 {
     return(sRuleExprAst.Lift(VoteMethods.NoneShouldPass).Select(_ => Unit.Value));
 }
Example #14
0
 public static RuleExprAst <Unit, RuleExprContext <Unit> > Lift(this RuleExprAst <Unit, RuleExprContext <string> > sRuleExprAst)
 {
     return(sRuleExprAst.Lift(VoteMethods.AllShouldPass));
 }
 public static RuleExprAst <S, RuleExprContext> ApplyTransform <T, S, RuleExprContext>(this RuleExprAst <T, RuleExprContext> expr, Expression <Func <RuleExprContext, (Option <T>, RuleExprContext), (Option <S>, RuleExprContext)> > transform)