private static (MethodInfo, Type, Type, Type) MakeMonadTransMethod <TUnlifted, TLifted, TInner, TSource, TResult>(this IMonadTransformer <TUnlifted, TLifted, TInner, TSource> transformer, string methodName)
/// <summary> /// Creates a <see cref="Func{T1, T2, TResult}"/> which runs <see cref="IMonadTransformer{TUnlifted, TLifted, TInner, TSource}.BindT{TUnliftedResult, TLiftedResult, TInnerResult, TResult}(Func{TSource, IMonadTransformer{TUnliftedResult, TLiftedResult, TInnerResult, TResult}})"/>, doing the type variable replacement at runtime. /// </summary> /// <typeparam name="TUnlifted">The unlifted value.</typeparam> /// <typeparam name="TLifted">The lifted value, containing the inner value.</typeparam> /// <typeparam name="TInner">The inner value.</typeparam> /// <typeparam name="TSource">The raw value.</typeparam> /// <typeparam name="TResult">The result-type.</typeparam> /// <param name="transformer">The transformer whose <see cref="IMonadTransformer{TUnlifted, TLifted, TInner, TSource}.BindT{TUnliftedResult, TLiftedResult, TInnerResult, TResult}(Func{TSource, IMonadTransformer{TUnliftedResult, TLiftedResult, TInnerResult, TResult}})"/>-function to use.</param> public static Func <IMonad <TSource>, Func <TSource, IMonad <TResult> >, IMonad <TResult> > MakeBind <TUnlifted, TLifted, TInner, TSource, TResult>(this IMonadTransformer <TUnlifted, TLifted, TInner, TSource> transformer) where TUnlifted : IMonad <TSource> where TLifted : IMonad <TInner> where TInner : IMonad <TSource> { var(method, unlifted, lifted, inner) = MakeMonadTransMethod <TUnlifted, TLifted, TInner, TSource, TResult>(transformer, "BindT"); var resultRetType = typeof(IMonadTransformer <, , ,>) .MakeGenericType( unlifted, lifted, inner, typeof(TResult)); var pF = Expression.Parameter(typeof(Func <TSource, IMonad <TResult> >), "f"); var pY = Expression.Parameter(typeof(TSource), "y"); var pX = Expression.Parameter(typeof(IMonad <TSource>), "x"); var bind = Expression.Lambda <Func <IMonad <TSource>, Func <TSource, IMonad <TResult> >, IMonad <TResult> > >( Expression.Call( Expression.Convert(pX, transformer.GetType()), method, Expression.Lambda( Expression.Convert(Expression.Invoke(pF, pY), resultRetType) , pY)), pX, pF); return(bind.Compile()); }
/// <summary> /// Creates a <see cref="Func{T1, T2, TResult}"/> which runs <see cref="IMonadTransformer{TUnlifted, TLifted, TInner, TSource}.ApT{TUnliftedFunc, TLiftedFunc, TInnerFunc, TUnliftedResult, TLiftedResult, TInnerResult, TResult}(IMonadTransformer{TUnliftedFunc, TLiftedFunc, TInnerFunc, Func{TSource, TResult}})"/>, doing the type variable replacement at runtime. /// </summary> /// <typeparam name="TUnlifted">The unlifted value.</typeparam> /// <typeparam name="TLifted">The lifted value, containing the inner value.</typeparam> /// <typeparam name="TInner">The inner value.</typeparam> /// <typeparam name="TSource">The raw value.</typeparam> /// <typeparam name="TResult">The result-type.</typeparam> /// <param name="transformer">The transformer whose <see cref="IMonadTransformer{TUnlifted, TLifted, TInner, TSource}.ApT{TUnliftedFunc, TLiftedFunc, TInnerFunc, TUnliftedResult, TLiftedResult, TInnerResult, TResult}(IMonadTransformer{TUnliftedFunc, TLiftedFunc, TInnerFunc, Func{TSource, TResult}})"/>-function to use.</param> public static Func <IApplicative <TSource>, IApplicative <Func <TSource, TResult> >, IApplicative <TResult> > MakeAp <TUnlifted, TLifted, TInner, TSource, TResult>(this IMonadTransformer <TUnlifted, TLifted, TInner, TSource> transformer) where TUnlifted : IMonad <TSource> where TLifted : IMonad <TInner> where TInner : IMonad <TSource> { var unliftedFunc = typeof(TUnlifted).ReplaceTypeVariable(typeof(TSource), typeof(Func <TSource, TResult>)); var liftedFunc = typeof(TLifted).ReplaceTypeVariable(typeof(TSource), typeof(Func <TSource, TResult>)); var innerFunc = typeof(TInner).ReplaceTypeVariable(typeof(TSource), typeof(Func <TSource, TResult>)); var unliftedResult = typeof(TUnlifted).ReplaceTypeVariable(typeof(TSource), typeof(TResult)); var liftedResult = typeof(TLifted).ReplaceTypeVariable(typeof(TSource), typeof(TResult)); var innerResult = typeof(TInner).ReplaceTypeVariable(typeof(TSource), typeof(TResult)); var interfaceType = typeof(IMonadTransformer <TUnlifted, TLifted, TInner, TSource>); var interfaceMethod = interfaceType.GetMethod("ApT"); var im = transformer.GetType().GetInterfaceMap(interfaceType); var index = Array.IndexOf(im.InterfaceMethods, interfaceMethod); var mi = im.TargetMethods[index]; var method = mi.MakeGenericMethod(unliftedFunc, liftedFunc, innerFunc, unliftedResult, liftedResult, innerResult, typeof(TResult)); var fType = typeof(IMonadTransformer <, , ,>) .MakeGenericType( unliftedFunc, liftedFunc, innerFunc, typeof(Func <TSource, TResult>)); var pF = Expression.Parameter(typeof(IApplicative <Func <TSource, TResult> >), "f"); var pX = Expression.Parameter(typeof(IApplicative <TSource>), "x"); var ap = Expression.Lambda <Func <IApplicative <TSource>, IApplicative <Func <TSource, TResult> >, IApplicative <TResult> > >( Expression.Call( Expression.Convert(pX, transformer.GetType()), method, Expression.Convert(pF, fType)), pX, pF); return(ap.Compile()); }
/// <summary> /// Creates a <see cref="Func{T1, T2, TResult}"/> which runs <see cref="IMonadTransformer{TUnlifted, TLifted, TInner, TSource}.PureT{TUnliftedResult, TLiftedResult, TInnerResult, TResult}(TResult)"/>, doing the type variable replacement at runtime. /// </summary> /// <typeparam name="TUnlifted">The unlifted value.</typeparam> /// <typeparam name="TLifted">The lifted value, containing the inner value.</typeparam> /// <typeparam name="TInner">The inner value.</typeparam> /// <typeparam name="TSource">The raw value.</typeparam> /// <typeparam name="TResult">The result-type.</typeparam> /// <param name="transformer">The transformer whose <see cref="IMonadTransformer{TUnlifted, TLifted, TInner, TSource}.PureT{TUnliftedResult, TLiftedResult, TInnerResult, TResult}(TResult)"/>-function to use.</param> public static Func <IApplicative <TSource>, TResult, IApplicative <TResult> > MakePure <TUnlifted, TLifted, TInner, TSource, TResult>(this IMonadTransformer <TUnlifted, TLifted, TInner, TSource> transformer) where TUnlifted : IMonad <TSource> where TLifted : IMonad <TInner> where TInner : IMonad <TSource> { var method = MakeMonadTransMethod <TUnlifted, TLifted, TInner, TSource, TResult>(transformer, "PureT").Item1; var pY = Expression.Parameter(typeof(TResult), "y"); var pX = Expression.Parameter(typeof(IApplicative <TSource>), "x"); var pure = Expression.Lambda <Func <IApplicative <TSource>, TResult, IApplicative <TResult> > >( Expression.Call( Expression.Convert(pX, transformer.GetType()), method, pY), pX, pY).Compile(); return(pure); }
/// <summary> /// Creates a <see cref="Func{T1, T2, TResult}"/> which runs <see cref="IMonadTransformer{TUnlifted, TLifted, TInner, TSource}.MapT{TUnliftedResult, TLiftedResult, TInnerResult, TResult}(Func{TSource, TResult})"/>, doing the type variable replacement at runtime. /// </summary> /// <typeparam name="TUnlifted">The unlifted value.</typeparam> /// <typeparam name="TLifted">The lifted value, containing the inner value.</typeparam> /// <typeparam name="TInner">The inner value.</typeparam> /// <typeparam name="TSource">The raw value.</typeparam> /// <typeparam name="TResult">The result-type.</typeparam> /// <param name="transformer">The transformer whose <see cref="IMonadTransformer{TUnlifted, TLifted, TInner, TSource}.MapT{TUnliftedResult, TLiftedResult, TInnerResult, TResult}(Func{TSource, TResult})"/>-function to use.</param> public static Func <Func <TSource, TResult>, IFunctor <TSource>, IFunctor <TResult> > MakeMap <TUnlifted, TLifted, TInner, TSource, TResult>(this IMonadTransformer <TUnlifted, TLifted, TInner, TSource> transformer) where TUnlifted : IMonad <TSource> where TLifted : IMonad <TInner> where TInner : IMonad <TSource> { var method = MakeMonadTransMethod <TUnlifted, TLifted, TInner, TSource, TResult>(transformer, "MapT").Item1; var pF = Expression.Parameter(typeof(Func <TSource, TResult>), "f"); var pX = Expression.Parameter(typeof(IFunctor <TSource>), "x"); var map = Expression.Lambda <Func <Func <TSource, TResult>, IFunctor <TSource>, IFunctor <TResult> > >( Expression.Call( Expression.Convert(pX, transformer.GetType()), method, pF), pF, pX).Compile(); return(map); }
/// <inheritdoc /> public IMonadTransformer <TUnliftedResult, TLiftedResult, TInnerResult, TResult> ApT <TUnliftedFunc, TLiftedFunc, TInnerFunc, TUnliftedResult, TLiftedResult, TInnerResult, TResult>(IMonadTransformer <TUnliftedFunc, TLiftedFunc, TInnerFunc, Func <TSource, TResult> > f) where TUnliftedFunc : IMonad <Func <TSource, TResult> > where TLiftedFunc : IMonad <TInnerFunc> where TInnerFunc : IMonad <Func <TSource, TResult> > where TUnliftedResult : IMonad <TResult> where TLiftedResult : IMonad <TInnerResult> where TInnerResult : IMonad <TResult> { var m_f = (MaybeT <TUnliftedFunc, TLiftedFunc, TInnerFunc, Func <TSource, TResult> >)f; var m_x = this; return(m_f.BindT(y => { return m_x.MapT <TUnliftedResult, TLiftedResult, TInnerResult, TResult>(x => { return y(x); }); })); }