Exemple #1
0
 private static (MethodInfo, Type, Type, Type) MakeMonadTransMethod <TUnlifted, TLifted, TInner, TSource, TResult>(this IMonadTransformer <TUnlifted, TLifted, TInner, TSource> transformer, string methodName)
Exemple #2
0
        /// <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());
        }
Exemple #3
0
        /// <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());
        }
Exemple #4
0
        /// <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);
        }
Exemple #5
0
        /// <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);
        }
Exemple #6
0
        /// <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);
                });
            }));
        }