public void If_WithFuncOfBooleanAndThenMonadType() // M<T> If<T>(Func<Boolean>, M<T>)
        {
            var spec = MethodSpecificationBuilder
                       .Named("If")
                       .IsStatic()
                       .IsPublic()
                       .IsNotExtensionMethod()
                       .IsOpenGeneric()

                       .GenericArgument(ga => ga
                                        .Named("T")
                                        .AtIndex(0)
                                        .CanBeReferenceType()
                                        .CanBeValueType())

                       .HasParameters(2)
                       .Parameter((m, p) => p
                                  .Named("predicate")
                                  .AtIndex(0)
                                  .Type(t => t.IsEqualTo(typeof(Func <bool>))))

                       .Parameter((m, p) => p
                                  .Named("then")
                                  .AtIndex(1)
                                  .Type(t => t.IsEqualTo(m.ReturnType)))

                       .Returns((m, t) => t
                                .IsEqualTo(MonadType.MakeGenericType(m.ReturnType.GetGenericArguments())));

            Assert.IsNotNull(ExtensionType.GetMethods().Single(spec.ToFunc()));
        }
        public void Defer_WithFunctionThatReturnsMonadType() // M<T> Defer<T>(Func<M<T>>)
        {
            var spec = MethodSpecificationBuilder
                       .Named("Defer")
                       .IsStatic()
                       .IsNotExtensionMethod()
                       .IsPublic()
                       .IsOpenGeneric()

                       .GenericArgument(ga => ga
                                        .Named("T")
                                        .AtIndex(0)
                                        .CanBeReferenceType()
                                        .CanBeValueType())

                       .HasParameters(1)
                       .Parameter((m, p) => p
                                  .Named("computation")
                                  .AtIndex(0)
                                  .Type(t => t.IsEqualTo(typeof(Func <>).MakeGenericType(m.ReturnType))))

                       .Returns((m, t) => t
                                .IsEqualTo(MonadType.MakeGenericType(m.ReturnType.GetGenericArguments())));

            Assert.IsNotNull(ExtensionType.GetMethods().Single(spec.ToFunc()));
        }