Example #1
0
        void AddCreatorDocs(CodeTypeDeclaration type, CodeMemberMethod method, int w, int n)
        {
            var tp   = Types.GetTypeParameter(n, w);
            var idx  = XmlDocs.GetIndex(tp);
            var fold = type.GetMethods("Fold").First();

            method.Comments.AddDocs(
                XmlDocs.Param("value",
                              "  A <typeparamref name=\"" + tp + "\" /> containing the value",
                              "  to provide to the " + idx,
                              "  " + XmlDocs.See(DefaultNamespace, type, fold),
                              "  delegate."
                              ),
                XmlDocs.Summary(
                    "  Creates a " + XmlDocs.See(DefaultNamespace, type) + " instance which",
                    "  holds a <typeparamref name=\"" + tp + "\" /> value."
                    ),
                XmlDocs.Returns(
                    "  A " + XmlDocs.See(DefaultNamespace, type) + " instance which holds a ",
                    "  holds a <typeparamref name=\"" + tp + "\" /> value."
                    ),
                XmlDocs.Remarks(
                    "  <para>",
                    "   When",
                    "   " + XmlDocs.See(DefaultNamespace, type, fold),
                    "   is invoked,",
                    "   the returned " + XmlDocs.See(DefaultNamespace, type) + " instance",
                    "   will invoke the " + idx + " delegate",
                    "   for conversions.",
                    "  </para>"
                    ),
                XmlDocs.ArgumentNullException("value")
                );
        }
Example #2
0
 void AddFoldDocs(CodeTypeDeclaration type, CodeMemberMethod method, int n)
 {
     method.Comments.AddDocs(
         XmlDocs.TypeParam("TResult",
                           "  The type to convert the " + XmlDocs.See(DefaultNamespace, type) + " to."
                           ),
         GetFoldParametersDocs(type, n),
         XmlDocs.Summary(
             "  Converts a " + XmlDocs.See(DefaultNamespace, type) + " into a <typeparamref name=\"TResult\" /> value."
             ),
         XmlDocs.Returns(
             "  A <typeparamref name=\"TResult\" /> as generated by one",
             "  of the conversion delegate parameters."
             ),
         XmlDocs.Remarks(
             "  <para>",
             "   Converts a " + XmlDocs.See(DefaultNamespace, type) + " into a <typeparamref name=\"TResult\" />",
             "   by invoking one of the provided delegate parameters.",
             "  </para>",
             "  <para>",
             "   The parameter which is invoked is predicated upon the internal position of",
             "   the value held.  For example, if the internal value is in the first position ",
             "   (i.e. " + XmlDocs.See(DefaultNamespace, type, type.GetMethods(A(0)).First()),
             "   was used to create the " + XmlDocs.See(DefaultNamespace, type) + " instance), then",
             "   <paramref name=\"a\" /> (the first delegate parameter) will be invoked to",
             "   convert the <typeparamref name=\"T1\" /> into a ",
             "   <typeparamref name=\"TResult\" />.",
             "  </para>"
             ),
         XmlDocs.ArgumentNullException(Enumerable.Range(0, n).Select(v => a(v)))
         );
 }
Example #3
0
        void AddEqualsDocs(CodeTypeDeclaration type, CodeMemberMethod method, int n)
        {
            var et = XmlDocs.See(DefaultNamespace, type);

            method.Comments.AddDocs(
                XmlDocs.Param("obj",
                              "A " + et + "to compare this instance against."
                              ),
                XmlDocs.Summary(
                    "  Determines whether the current instance and the specified " + et + " have the same value."
                    ),
                XmlDocs.Returns(
                    "  <para>",
                    "   <see langword=\"true\"/> if each member of <paramref name=\"obj\"/>",
                    "   and the current instance have the same value (according to",
                    "   <see cref=\"M:System.Object.Equals(System.Object)\"/>); otherwise",
                    "   <see langword=\"false\"/> is returned.",
                    "  </para>"
                    ),
                XmlDocs.Remarks(
                    "  <para>",
                    "   This method checks for value equality",
                    "   (<see cref=\"M:System.Object.Equals(System.Object)\"/>), as defined by each",
                    "   value type.",
                    "  </para>"
                    )
                );
        }
Example #4
0
        CodeMemberMethod CreateAggregateMethod(int n)
        {
            var retType = new CodeTypeReference("TResult");
            var m       = new CodeMemberMethod()
            {
                Attributes = MemberAttributes.Public | MemberAttributes.Static,
                Name       = "Aggregate",
                ReturnType = retType,
            };

            for (int i = 0; i < n; ++i)
            {
                m.TypeParameters.Add(Types.GetTypeParameter(n, i));
            }
            m.TypeParameters.Add("TResult");

            var selfType = new CodeTypeReference("this Tuple", Types.GetTypeParameterReferences(n, false).ToArray());

            m.Parameters.Add(new CodeParameterDeclarationExpression(selfType, "self"));

            var funcType = Types.Func(n);

            m.Parameters.Add(new CodeParameterDeclarationExpression(funcType, "func"));

            m.Statements.AddCheck("Self", "self");
            m.Statements.AddCheck("Func", "func");
            m.Statements.Add(
                new CodeMethodReturnStatement(
                    new CodeDelegateInvokeExpression(
                        new CodeVariableReferenceExpression("func"),
                        Enumerable.Range(0, n).Select(p =>
                                                      new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("self"), Tuple.Item(n, p))).ToArray())));

            var tref  = "<see cref=\"T:Cadenza.Tuple{" + Types.GetTypeParameterList(n) + "}\" />";
            var props = string.Join(", ",
                                    Enumerable.Range(0, n).Select(p => "<see cref=\"P:Cadenza.Tuple`" + n + "." + Tuple.Item(n, p) + "\"/>").ToArray());

            m.Comments.AddDocs(
                XmlDocs.TypeParams(m.TypeParameters),
                XmlDocs.Param("self", "A " + tref + " to aggregate the values of."),
                XmlDocs.Param("func",
                              "A " + XmlDocs.See(funcType) + " which will be invoked, providing the values",
                              props,
                              "to <paramref name=\"func\"/> and ",
                              "returning the value returned by <paramref name=\"func\"/>."),
                XmlDocs.Summary(
                    "Converts the " + tref + " into a <typeparamref name=\"TResult\"/>."),
                XmlDocs.Returns(
                    "The <typeparamref name=\"TResult\"/> returned by <paramref name=\"func\"/>."),
                XmlDocs.Remarks(
                    "<para>",
                    " <block subset=\"none\" type=\"behaviors\">",
                    "  Passes the values " + props + " to ",
                    "  <paramref name=\"func\"/>, returning the value produced by ",
                    "  <paramref name=\"func\"/>.",
                    " </block>",
                    "</para>"),
                XmlDocs.ArgumentNullException(new[] { "self", "func" }));
            return(m);
        }
Example #5
0
        CodeMemberMethod CreateTupleGetHashCodeMethod(int n)
        {
            var m = new CodeMemberMethod()
            {
                Attributes = MemberAttributes.Override | MemberAttributes.Public,
                Name       = "GetHashCode",
                ReturnType = new CodeTypeReference(typeof(int)),
            };

            m.Statements.Add(new CodeVariableDeclarationStatement(typeof(int), "hc", new CodePrimitiveExpression(0)));
            for (int i = 0; i < n; ++i)
            {
                m.Statements.Add(new CodeSnippetStatement(
                                     string.Format("            hc ^= {0}.GetHashCode();", Tuple.Item(n, i))));
            }
            m.Statements.Add(
                new CodeMethodReturnStatement(new CodeVariableReferenceExpression("hc")));
            m.Comments.AddDocs(
                XmlDocs.Summary("Generates a hash code for the current instance."),
                XmlDocs.Returns("A <see cref=\"T:System.Int32\"/> containing the hash code for this instance."),
                XmlDocs.Remarks(
                    "<para>",
                    " <block subset=\"none\" type=\"note\">",
                    "  This method overrides <see cref=\"M:System.Object.GetHashCode\"/>.",
                    " </block>",
                    "</para>"));
            return(m);
        }
Example #6
0
        protected static CodeMemberMethod CreateComposeMethod(Func <int, int, int, CodeTypeReference> getSelfType, Func <int, int, int, CodeTypeReference> getRetType, int n, bool tret)
        {
            var selfType = getSelfType(n + 1, n, 1);
            var retType  = getRetType(n + 1, 0, n);
            var m        = new CodeMemberMethod()
            {
                Attributes = MemberAttributes.Public | MemberAttributes.Static,
                Name       = "Compose",
                ReturnType = retType,
            };

            for (int i = 0; i < n + 1; ++i)
            {
                m.TypeParameters.Add(Types.GetTypeParameter(n + 1, i));
            }
            if (tret)
            {
                m.TypeParameters.Add("TResult");
            }
            m.Parameters.Add(new CodeParameterDeclarationExpression(selfType, "self"));
            var composerType = new CodeTypeReference(
                Types.FuncType(n),
                Types.GetTypeParameterReferences(n + 1, 0, n + 1, false).ToArray());

            m.Parameters.Add(new CodeParameterDeclarationExpression(composerType, "composer"));
            m.Statements.AddCheck("Self", "self");
            m.Statements.AddCheck("Composer", "composer");
            var expr = new StringBuilder().Append("(");

            Values(expr, n, 0, n);
            expr.Append(") => self (composer (");
            Values(expr, n, 0, n);
            expr.Append("))");
            m.Statements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression(expr.ToString())));
            m.Comments.AddDocs(
                GetComposeTypeParameters(n, selfType, composerType, tret),
                XmlDocs.Summary("Creates a " + XmlDocs.See(retType) + " delegate."),
                XmlDocs.Param("self", "The " + XmlDocs.See(selfType) + " to compose."),
                XmlDocs.Param("composer", "The " + XmlDocs.See(composerType) + " to compose with <paramref name=\"self\" />."),
                XmlDocs.Returns(
                    "Returns a " + XmlDocs.See(retType) + " which, when invoked, will",
                    "invoke <paramref name=\"composer\"/> and pass the return value of",
                    "<paramref name=\"composer\" /> to <paramref name=\"self\" />."),
                XmlDocs.Remarks(
                    "<para>",
                    " Composition is useful for chaining delegates together, so that the",
                    " return value of <paramref name=\"composer\" /> is automatically used as",
                    " the input parameter for <paramref name=\"self\" />.",
                    "</para>",
                    "<code lang=\"C#\">",
                    "Func&lt;int,string> tostring = Lambda.F ((int n) => n.ToString ());",
                    "Func&lt;int, int>    doubler = Lambda.F ((int n) => n * 2);",
                    "Func&lt;int, string>",
                    "     double_then_tostring = tostring.Compose (doubler);",
                    "Console.WriteLine (double_then_tostring (5));",
                    "    // Prints \"10\";</code>"),
                XmlDocs.ArgumentNullException(new[] { "self", "composer" }));
            return(m);
        }
Example #7
0
        protected static CodeMemberMethod CreateCurryTupleMethod(Func <int, int, CodeTypeReference> getSelfType, Func <int, int, CodeTypeReference> getRetType, int n, int a, bool tret)
        {
            var selfType = getSelfType(n, 0);
            var retType  = getRetType(n, a);
            var m        = new CodeMemberMethod()
            {
                Attributes = MemberAttributes.Public | MemberAttributes.Static,
                Name       = "Curry",
                ReturnType = retType,
            };

            for (int i = 0; i < n; ++i)
            {
                m.TypeParameters.Add(Types.GetTypeParameter(n, i));
            }
            if (tret)
            {
                m.TypeParameters.Add("TResult");
            }
            m.Parameters.Add(new CodeParameterDeclarationExpression(selfType, "self"));
            var valuesType =
                new CodeTypeReference("Tuple", Types.GetTypeParameterReferences(n, 0, a, false).ToArray());

            m.Parameters.Add(new CodeParameterDeclarationExpression(valuesType, "values"));
            m.Statements.AddCheck("Self", "self");
            var expr = new StringBuilder().Append("(");

            Values(expr, n, a, n);
            expr.Append(") => self (values.Item1");
            for (int i = 1; i < a; ++i)
            {
                expr.Append(", ").Append("values.Item" + (i + 1));
            }
            if (a < n)
            {
                expr.Append(", ");
                Values(expr, n, a, n);
            }
            expr.Append(")");
            m.Statements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression(expr.ToString())));

            m.Comments.AddDocs(
                GetTypeParameters(n, selfType),
                XmlDocs.Summary("Creates a " + XmlDocs.See(retType) + " delegate."),
                XmlDocs.Param("self", "The " + XmlDocs.See(selfType) + " to curry."),
                XmlDocs.Param("values", "A value of type " + XmlDocs.See(valuesType) + " which contains the values to fix."),
                XmlDocs.Returns(
                    "Returns a " + XmlDocs.See(retType) + " which, when invoked, will",
                    "invoke <paramref name=\"self\"/> along with the provided fixed parameters."),
                XmlDocs.ArgumentNullException("self"));
            return(m);
        }
Example #8
0
        static CodeMemberMethod XF(int args)
        {
            var t = new CodeTypeReference("System.Linq.Expressions.Expression", Types.Func(args));
            var m = CreateMethod("XF", t, "expr", args, true);

            m.Comments.AddDocs(
                XmlDocs.TypeParams(m.TypeParameters, t),
                XmlDocs.Param("expr", "The " + XmlDocs.See(t) + " to return."),
                XmlDocs.Summary("Creates a " + XmlDocs.See(t) + " expression tree."),
                XmlDocs.Returns("Returns <paramref name=\"expr\" />.")
                );
            return(m);
        }
Example #9
0
        static CodeMemberMethod F(int args)
        {
            var t = Types.Func(args);
            var m = CreateMethod("F", t, "lambda", args, true);

            m.Comments.AddDocs(
                XmlDocs.TypeParams(m.TypeParameters, t),
                XmlDocs.Param("lambda", "The " + XmlDocs.See(t) + " to return."),
                XmlDocs.Summary("Creates a " + XmlDocs.See(t) + " delegate."),
                XmlDocs.Returns("Returns <paramref name=\"lambda\" />.")
                );
            return(m);
        }
Example #10
0
 void AddGetHashCodeDocs(CodeTypeDeclaration type, CodeMemberMethod method, int n)
 {
     method.Comments.AddDocs(
         XmlDocs.Summary("  Generates a hash code for the current instance."),
         XmlDocs.Returns("  A <see cref=\"T:System.Int32\"/> containing the hash code for this instance."),
         XmlDocs.Remarks(
             "  <para>",
             "   <block subset=\"none\" type=\"note\">",
             "    This method overrides <see cref=\"M:System.Object.GetHashCode\"/>.",
             "   </block>",
             "  </para>"
             )
         );
 }
Example #11
0
        CodeMemberMethod CreateTupleToStringMethod(int n, CodeTypeDeclaration tuple)
        {
            var m = new CodeMemberMethod()
            {
                Attributes = MemberAttributes.Override | MemberAttributes.Public,
                Name       = "ToString",
                ReturnType = new CodeTypeReference(typeof(string)),
            };
            Func <int, CodeMethodInvokeExpression> c = w =>
                                                       new CodeMethodInvokeExpression(
                new CodePropertyReferenceExpression(
                    new CodeThisReferenceExpression(),
                    Tuple.Item(n, w)),
                "ToString");

            var args = new List <CodeExpression> ();

            args.Add(new CodePrimitiveExpression("("));
            args.Add(c(0));
            for (int i = 1; i < n; ++i)
            {
                args.Add(new CodePrimitiveExpression(", "));
                args.Add(c(i));
            }
            args.Add(new CodePrimitiveExpression(")"));
            m.Statements.Add(
                new CodeMethodReturnStatement(
                    new CodeMethodInvokeExpression(
                        new CodeMethodReferenceExpression(
                            new CodeTypeReferenceExpression(typeof(string)),
                            "Concat"),
                        args.ToArray())));

            m.Comments.AddDocs(
                XmlDocs.Summary("Returns a <see cref=\"T:System.String\"/> representation of the value of the current instance."),
                XmlDocs.Returns("A <see cref=\"T:System.String\"/> representation of the value of the current instance."),
                XmlDocs.Remarks(
                    "<para>",
                    " <block subset=\"none\" type=\"behaviors\">",
                    "  Returns <c>(</c>, followed by a comma-separated list of the result of",
                    "  calling <see cref=\"M:System.Object.ToString\"/> on",
                    Enumerable.Range(0, n).Select(p =>
                                                  XmlDocs.See(DefaultNamespace, tuple, tuple.Members.OfType <CodeMemberProperty>().First(v => v.Name == Tuple.Item(n, p))) +
                                                  ", "),
                    "  followed by <c>)</c>.",
                    " </block>",
                    "</para>"));
            return(m);
        }
Example #12
0
        IEnumerable <string> GetCreators(CodeTypeDeclaration type, int n)
        {
            var targs  = Types.GetTypeParameterList(n);
            var targsc = string.Join(",", Enumerable.Range(0, n).Select(p => "`" + p).ToArray());

            for (int i = 0; i < n; ++i)
            {
                yield return("    <item><term><see cref=\"" +
                             XmlDocs.Cref(DefaultNamespace, type, type.GetMethods(A(i)).First()) +
                             "\" /></term></item>");

                yield return("    <item><term><see cref=\"M:Cadenza.Either{" + targs +
                             "}.op_Implicit(`" + i + ")~Cadenza.Either{" + targsc + "}\" /></term></item>");
            }
        }
Example #13
0
        static IEnumerable GetComposeTypeParameters(int n, CodeTypeReference selfType, CodeTypeReference composerType, bool tret)
        {
            for (int i = 0; i < n - 1; ++i)
            {
                yield return(XmlDocs.TypeParam(Types.GetTypeParameter(n + 1, i),
                                               "A " + XmlDocs.See(composerType) + " parameter type."));
            }
            yield return(XmlDocs.TypeParam(Types.GetTypeParameter(n + 1, n),
                                           "The " + XmlDocs.See(composerType) + " return type, and " + XmlDocs.See(selfType) + " argument type."));

            if (tret)
            {
                yield return(XmlDocs.TypeParam("TResult", "The " + XmlDocs.See(selfType) + " return type."));
            }
        }
Example #14
0
        CodeMemberMethod CreateToEnumerableMethod(int n)
        {
            var retType = new CodeTypeReference("System.Collections.Generic.IEnumerable", new CodeTypeReference(typeof(object)));
            var m       = new CodeMemberMethod()
            {
                Attributes = MemberAttributes.Public | MemberAttributes.Static,
                Name       = "ToEnumerable",
                ReturnType = retType,
            };

            for (int i = 0; i < n; ++i)
            {
                m.TypeParameters.Add(Types.GetTypeParameter(n, i));
            }

            var selfType = new CodeTypeReference("this Tuple", Types.GetTypeParameterReferences(n, false).ToArray());

            m.Parameters.Add(new CodeParameterDeclarationExpression(selfType, "self"));

            m.Statements.AddCheck("Self", "self");
            m.Statements.Add(
                new CodeMethodReturnStatement(
                    new CodeMethodInvokeExpression(
                        new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("TupleCoda"), "CreateToEnumerableIterator"),
                        new CodeVariableReferenceExpression("self"))));

            var tref  = "<see cref=\"T:Cadenza.Tuple{" + Types.GetTypeParameterList(n) + "}\" />";
            var props = string.Join(", ",
                                    Enumerable.Range(0, n).Select(p => "<see cref=\"P:Cadenza.Tuple`" + n + "." + Tuple.Item(n, p) + "\"/>").ToArray());

            m.Comments.AddDocs(
                XmlDocs.TypeParams(m.TypeParameters),
                XmlDocs.Param("self", "A " + tref + " to convert into an <see cref=\"T:System.Collections.Generic.IEnumerable{System.Object}\"/>."),
                XmlDocs.Summary(
                    "Converts the " + tref + " into a <see cref=\"T:System.Collections.Generic.IEnumerable{System.Object}\"/>."),
                XmlDocs.Returns(
                    "A <see cref=\"T:System.Collections.Generic.IEnumerable{System.Object}\"/>."),
                XmlDocs.Remarks(
                    "<para>",
                    " <block subset=\"none\" type=\"behaviors\">",
                    "  Passes the values " + props + " to ",
                    "  <paramref name=\"func\"/>, returning the value produced by ",
                    "  <paramref name=\"func\"/>.",
                    " </block>",
                    "</para>"),
                XmlDocs.ArgumentNullException("self"));
            return(m);
        }
Example #15
0
        protected static CodeMemberMethod CreateCurryMethod(Func <int, int, CodeTypeReference> getSelfType, Func <int, int, CodeTypeReference> getRetType, int n, int a, bool tret)
        {
            var selfType = getSelfType(n, 0);
            var retType  = getRetType(n, a);
            var m        = new CodeMemberMethod()
            {
                Attributes = MemberAttributes.Public | MemberAttributes.Static,
                Name       = "Curry",
                ReturnType = retType,
            };

            for (int i = 0; i < n; ++i)
            {
                m.TypeParameters.Add(Types.GetTypeParameter(n, i));
            }
            if (tret)
            {
                m.TypeParameters.Add("TResult");
            }
            m.Parameters.Add(new CodeParameterDeclarationExpression(selfType, "self"));
            for (int i = 0; i < a; ++i)
            {
                m.Parameters.Add(new CodeParameterDeclarationExpression(Types.GetTypeParameter(n, i), Value(n, i)));
            }
            m.Statements.AddCheck("Self", "self");
            var expr = new StringBuilder().Append("(");

            Values(expr, n, a, n);
            expr.Append(") => self (");
            Values(expr, n, 0, n);
            expr.Append(")");
            m.Statements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression(expr.ToString())));

            m.Comments.AddDocs(
                GetTypeParameters(n, selfType),
                XmlDocs.Summary("Creates a " + XmlDocs.See(retType) + " delegate."),
                XmlDocs.Param("self", "The " + XmlDocs.See(selfType) + " to curry."),
                Enumerable.Range(0, a).Select(p => XmlDocs.Param(Value(n, p),
                                                                 "A value of type <typeparamref name=\"" + Types.GetTypeParameter(n, p) + "\"/> to fix.")),
                XmlDocs.Returns(
                    "Returns a " + XmlDocs.See(retType) + " which, when invoked, will",
                    "invoke <paramref name=\"self\"/> along with the provided fixed parameters."),
                XmlDocs.ArgumentNullException("self"));
            return(m);
        }
Example #16
0
        IEnumerable <string> GetFoldParametersDocs(CodeTypeDeclaration type, int n)
        {
            for (int i = 0; i < n; ++i)
            {
                var tp = Types.GetTypeParameter(n, i);
                yield return("<param name=\"" + a(i) + "\">");

                yield return("  A <see cref=\"T:System.Func{" + tp + ",TResult}\" /> ");

                yield return("  used if the " + XmlDocs.See(DefaultNamespace, type) + " stores a ");

                yield return("  <typeparamref name=\"" + tp + "\" /> value into a ");

                yield return("  <typeparamref name=\"TResult\" /> value.");

                yield return("</param>");
            }
        }
Example #17
0
        CodeTypeDeclaration CreateTupleCodaType(int n)
        {
            var t = new CodeTypeDeclaration("TupleCoda")
            {
                IsClass   = true,
                IsPartial = true,
            };

            for (int i = 1; i <= n; ++i)
            {
                t.Members.Add(CreateAggregateMethod(i));
                t.Members.Add(CreateMatchMethod(i));
                t.Members.Add(CreateToEnumerableMethod(i));
                t.Members.Add(CreateCreateToEnumerableIteratorMethod(i));
            }
            t.Comments.AddDocs(
                XmlDocs.Summary("Extension methods on <c>Tuple</c> types."),
                XmlDocs.Remarks());
            return(t);
        }
Example #18
0
        static CodeMemberMethod RecFunc(int args)
        {
            var t = Types.Func(args);
            var m = new CodeMemberMethod()
            {
                Attributes = MemberAttributes.Static | MemberAttributes.Public,
                Name       = "RecFunc",
                ReturnType = t,
            };

            m.TypeParameters.AddRange(Types.GetTypeParameters(args, true).ToArray());
            var a = "lambda";

            m.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference("Func", t, t), a));
            m.Statements.ThrowWhenArgumentIsNull(a);
            var expr = AppendArgs(new StringBuilder(), args);

            expr.Append(" => lambda (RecFunc (lambda))");
            AppendArgs(expr, args);
            m.Statements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression(expr.ToString())));
            m.Comments.AddRange("From: http://blogs.msdn.com/madst/archive/2007/05/11/recursive-lambda-expressions.aspx");
            m.Comments.AddDocs(
                XmlDocs.TypeParams(m.TypeParameters, t),
                XmlDocs.Param("lambda", "The " + XmlDocs.See(t) + " to use."),
                XmlDocs.Summary("Creates a " + XmlDocs.See(t) + " delegate, which may be recursive."),
                XmlDocs.Returns("Returns a " + XmlDocs.See(t) + " which (eventually) invokes <paramref name=\"lambda\"/>."),
                XmlDocs.ArgumentNullException("lambda"),
                XmlDocs.Remarks(
                    "<para>",
                    "  The following example makes use of a recursive lambda:",
                    "</para>",
                    "<code lang=\"C#\">",
                    "  Func<int, int> factorial = Lambda.RecFunc<int, int> (".Replace("<", "&lt;"),
                    "      fac => x => x == 0 ? 1 : x * fac (x-1));",
                    "  Console.WriteLine (factorial (5));  // prints \"120\"",
                    "</code>"
                    )
                );
            return(m);
        }
Example #19
0
        CodeMemberMethod CreateCreateMethod(int n)
        {
            var retType = new CodeTypeReference("Cadenza.Tuple", Types.GetTypeParameterReferences(n, false).ToArray());
            var m       = new CodeMemberMethod()
            {
                Attributes = MemberAttributes.Public | MemberAttributes.Static,
                Name       = "Create",
                ReturnType = retType,
            };

            for (int i = 0; i < n; ++i)
            {
                m.TypeParameters.Add(Types.GetTypeParameter(n, i));
            }
            for (int i = 0; i < n; ++i)
            {
                m.Parameters.Add(
                    new CodeParameterDeclarationExpression(
                        new CodeTypeReference(Types.GetTypeParameter(n, i)), Tuple.item(n, i)));
            }
            m.Statements.Add(
                new CodeMethodReturnStatement(
                    new CodeObjectCreateExpression(
                        new CodeTypeReference("Cadenza.Tuple", Types.GetTypeParameterReferences(n, false).ToArray()),
                        Enumerable.Range(0, n).Select(p => new CodeVariableReferenceExpression(Tuple.item(n, p))).ToArray())));
            var tcref = "Cadenza.Tuple{" + Types.GetTypeParameterList(n) + "}";

            m.Comments.AddDocs(
                Enumerable.Range(0, n).Select(p => XmlDocs.TypeParam(Types.GetTypeParameter(n, p),
                                                                     string.Format("The {0} <see cref=\"T:{1}\" /> value type.", XmlDocs.GetIndex(p), tcref))),
                XmlDocs.Summary("Creates a <see cref=\"" + tcref + "\" />."),
                Enumerable.Range(0, n).Select(p => XmlDocs.Param(Tuple.item(n, p),
                                                                 string.Format("The {0} <see cref=\"T:{1}\" /> value.", XmlDocs.GetIndex(p), tcref))),
                XmlDocs.Returns(
                    "A <see cref=\"T:" + tcref + "\" /> initialized with the parameter values."),
                "<seealso cref=\"C:" + tcref + "(" +
                string.Join(",", Enumerable.Range(0, n)
                            .Select(p => "`" + p.ToString()).ToArray()) + ")\" />");
            return(m);
        }
Example #20
0
 protected virtual void AppendTypeName(CodeTypeReference type)
 {
     Cref.Append(XmlDocs.GetType(type));
 }
Example #21
0
        CodeTypeDeclaration CreateTupleCreatorType(int n)
        {
            var tuple = new CodeTypeDeclaration("Tuple")
            {
                TypeAttributes = TypeAttributes.Public,
                IsPartial      = true,
            };

            AddConditionalCompilationDirective(tuple, "!NET_4_0");
            var maxValues = new CodeMemberProperty()
            {
                Attributes = MemberAttributes.Public | MemberAttributes.Static,
                Name       = "MaxValues",
                Type       = new CodeTypeReference(typeof(int)),
                HasGet     = true,
                HasSet     = false,
            };

            maxValues.GetStatements.Add(
                new CodeMethodReturnStatement(new CodePrimitiveExpression(n)));
            maxValues.Comments.AddDocs(
                XmlDocs.Summary("The maximum number of Tuple types provided."),
                "<value>",
                "  The maximum number of Tuple types provided.",
                "</value>",
                XmlDocs.Remarks(
                    "  <para>",
                    "   Only tuples up to a certain \"arity\" are supported; for example,",
                    "   a <c>Tuple&lt;T1, T2, ..., T100&gt;</c> isn't supported (and won't",
                    "   likely ever be).",
                    "  </para>",
                    "  <para>",
                    "   <see cref=\"P:Cadenza.Tuple.MaxValues\" /> is the maximum number of",
                    "   values that the Tuple types support.  If you need to support",
                    "   more values, then you need to either live with potential boxing",
                    "   and use a e.g. <see cref=\"T:System.Collections.Generic.List{System.Object}\" />",
                    "   or nest Tuple instantiations, e.g. ",
                    "   <c>Tuple&lt;int, Tuple&lt;int, Tuple&lt;int, Tuple&lt;int, int>>>></c>.",
                    "   The problem with such nesting is that it becomes \"unnatural\" to access ",
                    "   later elements -- <c>t._2._2._2._2</c> to access the fifth value for",
                    "   the previous example.",
                    "  </para>"));
            tuple.Members.Add(maxValues);
            for (int i = 0; i < n; ++i)
            {
                tuple.Members.Add(CreateCreateMethod(i + 1));
            }
            tuple.Comments.AddDocs(
                XmlDocs.Summary("Utility methods to create Tuple instances."),
                XmlDocs.Remarks(
                    "<para>",
                    " Provides a set of <see cref=\"M:Cadenza.Tuple.Create\"/> methods so that",
                    " C# type inferencing can easily be used with tuples.  For example,",
                    " instead of:",
                    "</para>",
                    "<code lang=\"C#\">",
                    "Tuple&lt;int, long&gt; a = new Tuple&lt;int, long&gt; (1, 2L);</code>",
                    "<para>You can instead write:</para>",
                    "<code lang=\"C#\">",
                    "Tuple&lt;int, long&gt; b = Tuple.Create (1, 2L);",
                    "// or",
                    "var              c = Tuple.Create (1, 2L);</code>"));
            return(tuple);
        }
Example #22
0
        CodeMemberMethod CreateMatchMethod(int n)
        {
            var retType = new CodeTypeReference("TResult");
            var m       = new CodeMemberMethod()
            {
                Attributes = MemberAttributes.Public | MemberAttributes.Static,
                Name       = "Match",
                ReturnType = retType,
            };

            for (int i = 0; i < n; ++i)
            {
                m.TypeParameters.Add(Types.GetTypeParameter(n, i));
            }
            m.TypeParameters.Add("TResult");

            var selfType = new CodeTypeReference("this Tuple", Types.GetTypeParameterReferences(n, false).ToArray());

            m.Parameters.Add(new CodeParameterDeclarationExpression(selfType, "self"));

            var matchersType = new CodeTypeReference(
                new CodeTypeReference(Types.FuncType(n),
                                      Types.GetTypeParameterReferences(n, false)
                                      .Concat(new[] { new CodeTypeReference("Cadenza.Maybe", new[] { new CodeTypeReference("TResult") }) })
                                      .ToArray()),
                1);
            var matchersParam = new CodeParameterDeclarationExpression(matchersType, "matchers");

            matchersParam.CustomAttributes.Add(new CodeAttributeDeclaration("System.ParamArrayAttribute"));
            m.Parameters.Add(matchersParam);

            m.Statements.AddCheck("Self", "self");
            m.Statements.ThrowWhenArgumentIsNull("matchers");

            var loop = new StringBuilder();

            loop.Append("            foreach (var m in matchers) {\n");
            loop.Append("              var r = m (self.Item1");
            for (int i = 1; i < n; ++i)
            {
                loop.Append(", self.").Append(Tuple.Item(n, i));
            }
            loop.Append(");\n");
            loop.Append("              if (r.HasValue)\n");
            loop.Append("                return r.Value;\n");
            loop.Append("            }");
            m.Statements.Add(new CodeSnippetStatement(loop.ToString()));
            m.Statements.Add(
                new CodeThrowExceptionStatement(
                    new CodeObjectCreateExpression(
                        new CodeTypeReference("System.InvalidOperationException"),
                        new CodePrimitiveExpression("no match"))));

            var fref = "<see cref=\"T:System.Func{" + Types.GetTypeParameterList(n) + ",Cadenza.Maybe{TResult}}\" />";
            var tref = "<see cref=\"T:Cadenza.Tuple{" + Types.GetTypeParameterList(n) + "}\" />";

            m.Comments.AddDocs(
                XmlDocs.TypeParams(m.TypeParameters),
                XmlDocs.Param("self", "A " + tref + " to match against."),
                XmlDocs.Param("matchers", "A " + fref,
                              "array containing the conversion routines to use to convert ",
                              "the current " + tref + " instance into a ",
                              "<typeparamref name=\"TResult\" /> value."),
                XmlDocs.Summary(
                    "Converts the current " + tref + " instance into a <typeparamref name=\"TResult\"/>."),
                XmlDocs.Returns(
                    "The <typeparamref name=\"TResult\"/> returned by one of the <paramref name=\"matchers\"/>."),
                XmlDocs.Remarks(
                    "<para>",
                    " <block subset=\"none\" type=\"behaviors\">",
                    "  <para>",
                    "   The current " + tref + " instance is converted into a ",
                    "   <typeparamref name=\"TResult\" /> instance by trying each",
                    "   " + fref,
                    "   within <paramref name=\"matchers\" />.",
                    "  </para>",
                    "  <para>",
                    "   This method returns ",
                    "   <see cref=\"P:Cadenza.Maybe{TResult}.Value\" /> ",
                    "   for the first delegate to return a",
                    "   <see cref=\"T:Cadenza.Maybe{TResult}\" /> instance",
                    "   where <see cref=\"P:Cadenza.Maybe{TResult}.HasValue\" />",
                    "   is <see langword=\"true\" />.",
                    "  </para>",
                    "  <para>",
                    "   If no " + fref,
                    "   returns a ",
                    "   <see cref=\"T:Cadenza.Maybe{TResult}\" /> instance",
                    "   where <see cref=\"P:Cadenza.Maybe{TResult}.HasValue\" />",
                    "   is <see langword=\"true\" />, then an",
                    "   <see cref=\"T:System.InvalidOperationException\" /> is thrown.",
                    "  </para>",
                    " </block>",
                    " <code lang=\"C#\">",
                    "var    a = Tuple.Create (1, 2);",
                    "string b = a.Match (",
                    "    (t, v) =&gt; Match.When ( t + v == 3, \"foo!\"),",
                    "    (t, v) =&gt; \"*default*\".Just ());",
                    "Console.WriteLine (b);  // prints \"foo!\"</code>",
                    "</para>"),
                XmlDocs.ArgumentNullException(new[] { "self", "matchers" }),
                XmlDocs.Exception(typeof(InvalidOperationException),
                                  "None of the ",
                                  "<see cref=\"T:System.Func{TSource,Cadenza.Maybe{TResult}}\" />",
                                  "delegates within <paramref name=\"matchers\" /> returned a ",
                                  "<see cref=\"T:Cadenza.Maybe{TResult}\" /> instance where",
                                  "<see cref=\"P:Cadenza.Maybe{TResult}.HasValue\" /> was",
                                  "<see langword=\"true\" />."));
            return(m);
        }
Example #23
0
 protected static IEnumerable <IEnumerable <string> > GetTypeParameters(int n, CodeTypeReference selfType)
 {
     return(Enumerable.Range(0, n).Select(p => XmlDocs.TypeParam(Types.GetTypeParameter(n, p),
                                                                 "A " + XmlDocs.See(selfType) + " parameter type.")));
 }
Example #24
0
        protected static CodeMemberMethod CreateTraditionalCurryMethod(Func <int, int, CodeTypeReference> getSelfType, Func <int, int, CodeTypeReference> getRetType, int n, bool tret)
        {
            var selfType = getSelfType(n, 0);
            var retType  = getRetType(n, n - 1);

            for (int i = n - 2; i >= 0; --i)
            {
                retType = new CodeTypeReference("System.Func", new CodeTypeReference(Types.GetTypeParameter(n, i)), retType);
            }
            var m = new CodeMemberMethod()
            {
                Attributes = MemberAttributes.Public | MemberAttributes.Static,
                Name       = "Curry",
                ReturnType = retType,
            };

            for (int i = 0; i < n; ++i)
            {
                m.TypeParameters.Add(Types.GetTypeParameter(n, i));
            }
            if (tret)
            {
                m.TypeParameters.Add("TResult");
            }
            m.Parameters.Add(new CodeParameterDeclarationExpression(selfType, "self"));
            m.Statements.AddCheck("Self", "self");
            var expr = new StringBuilder();

            for (int i = 0; i < n; ++i)
            {
                expr.Append(Value(n, i)).Append(" => ");
            }
            expr.Append("self (");
            Values(expr, n, 0, n);
            expr.Append(")");
            m.Statements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression(expr.ToString())));
            var retDocs = new StringBuilder();

            if (retType.TypeArguments.Count > 1)
            {
                var rt = retType.TypeArguments [1];
                while (rt != null && rt.TypeArguments.Count > 1)
                {
                    retDocs.Append("return a ").Append(XmlDocs.See(rt)).Append(" which, when invoked, will ");
                    rt = rt.TypeArguments [1];
                }
                if (rt.TypeArguments.Count > 0)
                {
                    retDocs.Append("return a ").Append(XmlDocs.See(rt)).Append(" which, when invoked, will ");
                }
            }
            m.Comments.Add(new CodeCommentStatement("Currying method idea courtesy of:"));
            m.Comments.Add(new CodeCommentStatement("http://blogs.msdn.com/wesdyer/archive/2007/01/29/currying-and-partial-function-application.aspx"));
            m.Comments.AddDocs(
                XmlDocs.TypeParams(m.TypeParameters),
                XmlDocs.Param("self", "The " + XmlDocs.See(selfType) + " to curry."),
                XmlDocs.Summary("Creates a " + XmlDocs.See(retType) + " for currying."),
                XmlDocs.Returns(
                    "A " + XmlDocs.See(retType) + " which, when invoked, will ",
                    retDocs.ToString(),
                    "invoke <paramref name=\"self\"/>."),
                XmlDocs.Remarks(
                    "<para>",
                    " This is the more \"traditional\" view of currying, turning a method",
                    " which takes <c>(X * Y)-&gt;Z</c> (i.e. separate arguments) into a",
                    " <c>X -&gt; (Y -&gt; Z)</c> (that is a \"chain\" of nested Funcs such that",
                    " you provide only one argument to each Func until you provide enough",
                    " arguments to invoke the original method).",
                    "</para>",
                    "<code lang=\"C#\">",
                    "Func&lt;int,int,int,int&gt; function = (int a, int b, int c) =&gt; a + b + c;",
                    "Func&lt;int,Func&lt;int,Func&lt;int, int&gt;&gt;&gt; curry = function.Curry ();",
                    "Assert.AreEqual(6, curry (3)(2)(1));</code>"),
                XmlDocs.ArgumentNullException("self"));
            return(m);
        }
Example #25
0
        CodeMemberMethod AddTimingsDocs(CodeMemberMethod m, int n, CodeTypeDeclaration t, CodeMemberMethod full)
        {
            m.Comments.AddDocs(
                GetTypeParameters(n, m.Parameters [0].Type),
                XmlDocs.Summary("Get timing information for delegate invocations."),
                XmlDocs.Param("self", "The " + XmlDocs.See(m.Parameters [0].Type) + " to generate timings for."),
                GetTimingsParameters(n),
                XmlDocs.Param("runs", "An <see cref=\"T:System.Int32\" /> containing the number of <see cref=\"T:System.TimeSpan\" /> values to return."),
                full == null
                                                ? XmlDocs.Param("loopsPerRun",
                                                                "An <see cref=\"T:System.Int32\" /> containing the number of " +
                                                                "times to invoke <paramref name=\"self\" /> for each " +
                                                                "<see cref=\"T:System.TimeSpan\" /> value returned.")
                                                : new[] { "" },
                XmlDocs.Returns(
                    "An " + XmlDocs.See(m.ReturnType),
                    "which will return the timing information for <paramref name=\"self\" />."));
            if (full != null)
            {
                var alt = new StringBuilder().Append("self.Timing (");
                Values(alt, n, 0, n);
                if (n > 0)
                {
                    alt.Append(", ");
                }
                alt.Append("runs, 1)");
                m.Comments.AddDocs(
                    XmlDocs.Remarks(
                        "<para>",
                        " This is equivalent to calling",
                        " " + XmlDocs.See(DefaultNamespace, t, full),
                        " with a <paramref name=\"loopsPerRun\" /> value of <c>1</c>,",
                        " e.g. as if by calling <c>" + alt.ToString() + "</c>.",
                        "</para>"),
                    "<seealso cref=\"" + XmlDocs.Cref(DefaultNamespace, t, full) + "\" />");
            }
            else
            {
                m.Comments.AddDocs(XmlDocs.Remarks(
                                       "<para>",
                                       " Generates <paramref name=\"runs\" /> <see cref=\"T:System.TimeSpan\" />",
                                       " instances, in which each <c>TimeSpan</c> instance is the amount of time",
                                       " required to execute <paramref name=\"self\" /> for",
                                       " <paramref name=\"loopsPerRun\" /> times.",
                                       "</para>"));
            }
            m.Comments.AddDocs(
                XmlDocs.Exception(typeof(ArgumentException),
                                  "<para>",
                                  " <paramref name=\"runs\" /> is negative.",
                                  "</para>",
                                  full != null ? new object[0] : new object[] {
                "<para>-or-</para>",
                "<para>",
                " <paramref name=\"loopsPerRun\" /> is negative.",
                "</para>"
            }),
                XmlDocs.ArgumentNullException("self"));

            return(m);
        }
Example #26
0
        CodeMemberMethod CreateTupleEqualsMethod(int n, CodeTypeDeclaration tuple)
        {
            var m = new CodeMemberMethod()
            {
                Attributes = MemberAttributes.Override | MemberAttributes.Public,
                Name       = "Equals",
                ReturnType = new CodeTypeReference(typeof(bool)),
            };
            var t = "Tuple<" + Types.GetTypeParameterList(n) + ">";

            m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "obj"));
            m.Statements.Add(new CodeSnippetStatement(string.Format("            {0} o = obj as {0};", t)));
            m.Statements.Add(new CodeConditionStatement(
                                 new CodeBinaryOperatorExpression(
                                     new CodeVariableReferenceExpression("o"),
                                     CodeBinaryOperatorType.ValueEquality,
                                     new CodePrimitiveExpression(null)),
                                 new CodeMethodReturnStatement(new CodePrimitiveExpression(false))));
            Func <int, CodeMethodInvokeExpression> c = w =>
                                                       new CodeMethodInvokeExpression(
                new CodePropertyReferenceExpression(
                    new CodeTypeReferenceExpression(
                        new CodeTypeReference("System.Collections.Generic.EqualityComparer",
                                              new CodeTypeReference(new CodeTypeParameter(Types.GetTypeParameter(n, w))))),
                    "Default"),
                "Equals",
                new CodeFieldReferenceExpression(
                    new CodeThisReferenceExpression(), Tuple.item(n, w)),
                new CodeFieldReferenceExpression(
                    new CodeVariableReferenceExpression("o"), Tuple.item(n, w)));
            CodeExpression pred = c(0);

            for (int i = 1; i < n; ++i)
            {
                pred = new CodeBinaryOperatorExpression(
                    pred,
                    CodeBinaryOperatorType.BooleanAnd,
                    c(i));
            }
            m.Statements.Add(
                new CodeMethodReturnStatement(pred));
            m.Comments.AddDocs(
                XmlDocs.Param("obj", "A <see cref=\"T:System.Object\"/> to compare this instance against."),
                XmlDocs.Summary("Determines whether the current instance and the specified object have the same value."),
                XmlDocs.Returns(
                    "<para>",
                    " <see langword=\"true\"/> if <paramref name=\"obj\"/> is a",
                    " " + XmlDocs.See(DefaultNamespace, tuple) + " and each member of <paramref name=\"obj\"/>",
                    " and the current instance have the same value (according to",
                    " <see cref=\"M:System.Collections.Generic.EqualityComparer{T}.Equals(`0,`0)\" />); otherwise",
                    " <see langword=\"false\"/> is returned.",
                    "</para>"),
                XmlDocs.Remarks(
                    "<para>",
                    " This method checks for value equality",
                    " (<see cref=\"M:System.Collections.Generic.EqualityComparer{T}.Equals(`0,`0)\" />), as defined by each",
                    " value type.",
                    "</para>",
                    "<para>",
                    " <block subset=\"none\" type=\"note\">",
                    "  This method overrides <see cref=\"M:System.Object.Equals(System.Object)\"/>.",
                    " </block>",
                    "</para>"));
            return(m);
        }
Example #27
0
        CodeTypeDeclaration CreateTupleType(int n)
        {
            var tuple = new CodeTypeDeclaration("Tuple")
            {
                TypeAttributes = TypeAttributes.Public,
                IsPartial      = true,
            };

            AddConditionalCompilationDirective(tuple, "!NET_4_0");
            for (int i = 0; i < n; ++i)
            {
                tuple.TypeParameters.Add(Types.GetTypeParameter(n, i));
                tuple.Members.Add(new CodeMemberField(Types.GetTypeParameter(n, i), Tuple.item(n, i)));
                var p = new CodeMemberProperty()
                {
                    Attributes = MemberAttributes.Public | MemberAttributes.Final,
                    Name       = Tuple.Item(n, i),
                    HasGet     = true,
                    HasSet     = false,
                    Type       = new CodeTypeReference(Types.GetTypeParameter(n, i)),
                };
                p.GetStatements.Add(
                    new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), Tuple.item(n, i))));
                p.Comments.AddDocs(
                    XmlDocs.Summary(string.Format("The {0} tuple value.", XmlDocs.GetIndex(i))),
                    XmlDocs.Value("A <typeparamref name=\"" + Types.GetTypeParameter(n, i) + "\" /> which is the " +
                                  XmlDocs.GetIndex(i) + " tuple value."),
                    XmlDocs.Remarks(string.Format("The {0} tuple value.", XmlDocs.GetIndex(i))));
                tuple.Members.Add(p);
            }
            var c = new CodeConstructor()
            {
                Attributes = MemberAttributes.Public,
            };

            for (int i = 0; i < n; ++i)
            {
                c.Parameters.Add(new CodeParameterDeclarationExpression(Types.GetTypeParameter(n, i), Tuple.item(n, i)));
                c.Statements.Add(new CodeAssignStatement(
                                     new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), Tuple.item(n, i)),
                                     new CodeVariableReferenceExpression(Tuple.item(n, i))));
            }
            tuple.Members.Add(c);
            c.Comments.AddDocs(
                XmlDocs.Summary("Constructs and initializes a new " + XmlDocs.See(DefaultNamespace, tuple) + " instance."),
                Enumerable.Range(0, n).Select(p => XmlDocs.Param(Tuple.item(n, p),
                                                                 "A <typeparamref name=\"" + Types.GetTypeParameter(n, p) + "\"/> which is used to initialize the " +
                                                                 XmlDocs.See(DefaultNamespace, tuple, tuple.Members.OfType <CodeMemberProperty>().First(v => v.Name == Tuple.Item(n, p))) +
                                                                 " property.")),
                XmlDocs.Remarks(
                    "<para>",
                    "  Constructs and initializes a new " + XmlDocs.See(DefaultNamespace, tuple) + " instance.",
                    "</para>"));
            tuple.Members.Add(CreateTupleEqualsMethod(n, tuple));
            tuple.Members.Add(CreateTupleGetHashCodeMethod(n));
            tuple.Members.Add(CreateTupleToStringMethod(n, tuple));
            tuple.Comments.AddDocs(
                XmlDocs.TypeParams(tuple.TypeParameters),
                XmlDocs.Summary("A strongly-typed sequence of " + n + " variously typed values."),
                XmlDocs.Remarks(
                    "<para>",
                    " A <c>Tuple</c> is an immutable, strongly typed sequence of variously",
                    " typed values with each value lacking an otherwise meaningful name aside",
                    " from its position.",
                    "</para>"));
            return(tuple);
        }
Example #28
0
        CodeTypeDeclaration CreateEither(int n)
        {
            var either = new CodeTypeDeclaration("Either")
            {
                TypeAttributes = TypeAttributes.Public | TypeAttributes.Abstract,
            };

            either.BaseTypes.Add(new CodeTypeReference("IEquatable", GetEitherType(n)));
            either.TypeParameters.AddRange(Types.GetTypeParameters(n, false));
            either.Members.Add(new CodeConstructor()
            {
                Attributes = MemberAttributes.Private,
            });
            for (int i = 0; i < n; ++i)
            {
                either.Members.Add(CreateImplicitCreator(either, i, n));
                either.Members.Add(CreateCreator(either, i, n));
            }
            either.Members.Add(CreateFold(either, n));
            either.Members.Add(CreateCheckFolders(n));
            either.Members.Add(CreateEqualsObject());
            either.Members.Add(CreateEquals(n));
            either.Members.Add(CreateGetHashCode());
            for (int i = 0; i < n; ++i)
            {
                either.Members.Add(CreateHandler(i, n));
            }
            either.Comments.AddDocs(
                XmlDocs.TypeParams(either.TypeParameters),
                XmlDocs.Summary("A union of " + n + " values."),
                "<remarks>",
                "  <para>",
                "   An <c>Either</c> is an immutable, strongly typed union of variously ",
                "   typed values with each value lacking an otherwise meaningful name aside ",
                "   from its position, which is not exposed.  It stores only one (non-null) ",
                "   value from a set of types (as determined by the type parameter list).",
                "  </para>",
                "  <para>",
                "   The value held by a " + XmlDocs.See(DefaultNamespace, either) + " instance",
                "   can be converted into a value by using the ",
                "   <see cref=\"" + XmlDocs.Cref(DefaultNamespace, either, either.GetMethods("Fold").First()) + "\" /> method.",
                "   <c>Fold</c> takes a list of delegates to perform the conversion; the",
                "   delegate used to perform the conversion is based upon the internal ",
                "   position of the value stored.",
                "  </para>",
                "  <para>",
                "   <c>Either</c> instances are created through one of the following",
                "   creation methods:",
                "  </para>",
                "  <list type=\"bullet\">",
                GetCreators(either, n),
                "  </list>",
                "  <code lang=\"C#\">",
                "  var a = Either&lt;double, string&gt;.A (Math.PI);   // value stored in 1st position",
                "  ",
                "  int r = a.Fold (",
                "          v => (int) v,                                 // 1st position converter",
                "          v => v.Length);                               // 2nd position converter",
                "  ",
                "  Console.WriteLine (r);                        // prints 3",
                " ",
                "  // alternatively...",
                "  Either&lt;double, string&gt; b = \"value\";           // value stored in 2nd position",
                "  Console.WriteLine (b.Fold (v => v.ToString(), v => v));",
                "                                                // prints \"value\"</code>",
                "</remarks>"
                );
            for (int i = 0; i < n; ++i)
            {
                AddCreatorDocs(either, either.GetMethods(A(i)).First(), i, n);
            }
            AddFoldDocs(either, either.GetMethods("Fold").First(), n);
            AddEqualsObjectDocs(either,
                                either.GetMethods("Equals").First(m => m.Parameters [0].Type.BaseType == "System.Object"), n);
            AddEqualsDocs(either,
                          either.GetMethods("Equals").First(m => m.Parameters [0].Type.BaseType != "System.Object"), n);
            AddGetHashCodeDocs(either, either.GetMethods("GetHashCode").First(), n);
            return(either);
        }
Example #29
0
 static IEnumerable GetTimingsParameters(int n)
 {
     return(Enumerable.Range(0, n).Select(p =>
                                          XmlDocs.Param(Value(n, p), "The " + XmlDocs.GetIndex(Value(n, p)) + " <paramref name=\"self\"/> parameter value.")));
 }
Example #30
0
        protected override IEnumerable <CodeTypeDeclaration> GetRocksNamespaceTypes()
        {
            var dr = new CodeTypeDeclaration("FuncCoda")
            {
                IsPartial      = true,
                TypeAttributes = TypeAttributes.Public,
            };

            for (int i = 0; i <= TypeParameterCount; ++i)
            {
                dr.Members.AddRange(CreateCurryFuncs(i));
                dr.Members.AddRange(CreateCurryTupleFuncs(i));
                dr.Members.AddRange(CreateTraditionalCurryFuncs(i));
                dr.Members.Add(CreateComposeMethod(Types.ThisFunc, Types.Func, i, true));
            }
            dr.Comments.AddDocs(
                XmlDocs.Summary(
                    "Provides extension methods on <see cref=\"T:System.Func{TResult}\"/>",
                    "and related delegates."),
                XmlDocs.Remarks(
                    "<para>",
                    " " + XmlDocs.See(DefaultNamespace, dr) + " provides methods methods for:",
                    "</para>",
                    "<list type=\"bullet\">",
                    " <item><term>",
                    "  Delegate currying and partial application (<see cref=\"M:Cadenza.DelegateCoda.Curry\" />)",
                    " </term></item>",
                    " <item><term>",
                    "  Delegate composition (<see cref=\"M:Cadenza.DelegateCoda.Compose\" />)",
                    " </term></item>",
                    " <item><term>",
                    "  Timing generation (<see cref=\"M:Cadenza.DelegateCoda.Timings\" />)",
                    " </term></item>",
                    "</list>",
                    "<para>",
                    " Currying via partial application is a way to easily transform ",
                    " functions which accept N arguments into functions which accept ",
                    " N-1 arguments, by \"fixing\" arguments with a value.",
                    "</para>",
                    "<code lang=\"C#\">",
                    "// partial application:",
                    "Func&lt;int,int,int,int&gt; function = (int a, int b, int c) => a + b + c;",
                    "Func&lt;int,int,int&gt;     f_3      = function.Curry (3);",
                    "Func&lt;int&gt;             f_321    = function.Curry (3, 2, 1);",
                    "Console.WriteLine (f_3 (2, 1));  // prints (3 + 2 + 1) == \"6\"",
                    "Console.WriteLine (f_321 ());    // prints (3 + 2 + 1) == \"6\"</code>",
                    "<para>",
                    " \"Traditional\" currying converts a delegate that accepts N arguments",
                    " into a delegate which accepts only one argument, but when invoked may ",
                    " return a further delegate (etc.) until the final value is returned.",
                    "</para>",
                    "<code lang=\"C#\">",
                    "// traditional currying:",
                    "Func&lt;int, Func&lt;int, Func&lt;int, int&gt;&gt;&gt; curry = function.Curry ();",
                    "Func&lt;int, Func&lt;int, int&gt;&gt;            fc_1  = curry (1);",
                    "Func&lt;int, int&gt;                       fc_12 = fc_1 (2);",
                    "Console.WriteLine (fc_12 (3));        // prints (3 + 2 + 1) == \"6\"",
                    "Console.WriteLine (curry (3)(2)(1));  // prints (3 + 2 + 1) == \"6\"</code>",
                    "<para>",
                    " Composition is a way to easy chain (or pipe) together multiple delegates",
                    " so that the return value of a \"composer\" delegate is used as the input ",
                    " parameter for the chained delegate:",
                    "</para>",
                    "<code lang=\"C#\">",
                    "Func&lt;int,string> tostring = Lambda.F ((int n) => n.ToString ());",
                    "Func&lt;int, int>    doubler = Lambda.F ((int n) => n * 2);",
                    "Func&lt;int, string>",
                    "     double_then_tostring = tostring.Compose (doubler);",
                    "Console.WriteLine (double_then_tostring (5));",
                    "    // Prints \"10\";</code>",
                    "<para>",
                    " All possible argument and return delegate permutations are provided",
                    " for the <see cref=\"T:System.Func{T,TResult}\"/> and related types.",
                    "</para>")
                );
            yield return(dr);
        }