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); //}; }
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 }); }
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) }); }
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'); // } }
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 }); }
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); //}; }
// 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 }); }
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()); }
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 }); }
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); //}; }
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); //}; }
public static RuleExprAst <Unit, RuleExprContext <Unit> > Lift(this RuleExprAst <Amount, RuleExprContext <string> > sRuleExprAst) { return(sRuleExprAst.Lift(VoteMethods.MinValue).Apply()); }
public static RuleExprAst <Unit, RuleExprContext <Unit> > Lift(this RuleExprAst <FailUnit, RuleExprContext <string> > sRuleExprAst) { return(sRuleExprAst.Lift(VoteMethods.NoneShouldPass).Select(_ => Unit.Value)); }
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)