public void ReturnTypeIsCorrect()
        {
            var monad = new UnauthorizedMonad <String>();

            var asserterVisitor = new AssertUnauthorizedVisitor <String>();

            monad.Accept(asserterVisitor);
        }
        public void BindPropagatesTheType()
        {
            var firstMonad  = new UnauthorizedMonad <Int32>();
            var secondMonad = firstMonad.Bind(val => new ValueMonad <Int32>(val + 1));

            var asserterVisitor = new AssertUnauthorizedVisitor <Int32>();

            secondMonad.Accept(asserterVisitor);
        }
        public void BindPropagatesTheErrorMore()
        {
            var asserterVisitor = new AssertUnauthorizedVisitor <Int32>();

            new UnauthorizedMonad <Int32>()
            .Bind(val => new ValueMonad <Int32>(val + 1))
            .Bind(val => new ValueMonad <Int32>(val + 2))
            .Bind(val => new ValueMonad <Int32>(val + 3))
            .Bind(val => new ValueMonad <Int32>(val + 4))
            .Accept(asserterVisitor);
        }
        public void BindDoesntExecuteAfterError()
        {
            var asserterVisitor = new AssertUnauthorizedVisitor <Int32>();

            ErrorMonad <Int32> Fail(Int32 value)
            {
                Assert.Fail();

                return(new ErrorMonad <Int32>("This should never execute"));
            }

            Assert.DoesNotThrow(() => new UnauthorizedMonad <Int32>().Bind(Fail));
        }