public void PlusTest()
    {
        var val = new Random(DateTime.Now.Millisecond).Next();

        Assert.AreEqual(Either <Void, string> .Right(str), Lrl(PlusO <string>())(Either <Void, string> .Right(str)));
        Assert.AreEqual(str, Rlr(PlusO <string>())(str));
        Assert.AreEqual(Either <Optional <string>, int> .Left(Optional <string> .From(str)),
                        Lrl(PlusS <string, int>())(Either <Optional <string>, int> .Left(Optional <string> .From(str))));
        Assert.AreEqual(Either <Optional <string>, int> .Left(Optional <string> .Empty()),
                        Lrl(PlusS <string, int>())(Either <Optional <string>, int> .Left(Optional <string> .Empty())));
        Assert.AreEqual(Either <Optional <string>, int> .Right(val),
                        Lrl(PlusS <string, int>())(Either <Optional <string>, int> .Right(val)));
        Assert.AreEqual(Optional <Either <string, int> > .From(Either <string, int> .Left(str)),
                        Rlr(PlusS <string, int>())(Optional <Either <string, int> > .From(Either <string, int> .Left(str))));
        Assert.AreEqual(Optional <Either <string, int> > .From(Either <string, int> .Right(val)),
                        Rlr(PlusS <string, int>())(Optional <Either <string, int> > .From(Either <string, int> .Right(val))));
        Assert.AreEqual(Optional <Either <string, int> > .Empty(),
                        Rlr(PlusS <string, int>())(Optional <Either <string, int> > .Empty()));
        Assert.AreEqual(Either <Unit, int> .Left(Unit.INSTANCE), Lrl(PlusSO_ <int>())(Either <Unit, int> .Left(Unit.INSTANCE)));
        Assert.AreEqual(Either <Unit, int> .Right(val), Lrl(PlusSO_ <int>())(Either <Unit, int> .Right(val)));
        Assert.AreEqual(Optional <int> .Empty(), Rlr(PlusSO_ <int>())(Optional <int> .Empty()));
        Assert.AreEqual(val, Rlr(PlusSO_ <int>())(Optional <int> .From(val)).Get());
        Assert.AreEqual(Either <Unit, int> .Left(Unit.INSTANCE), Lrl(PlusSO <int>())(Either <Unit, int> .Left(Unit.INSTANCE)));
        Assert.AreEqual(Either <Unit, int> .Right(val), Lrl(PlusSO <int>())(Either <Unit, int> .Right(val)));
        Assert.AreEqual(Optional <int> .Empty(), Rlr(PlusSO <int>())(Optional <int> .Empty()));
        Assert.AreEqual(val, Rlr(PlusSO <int>())(Optional <int> .From(val)).Get());
    }
 public void TwoTest()
 {
     Assert.IsTrue(Lrl(Two())(true));
     Assert.IsFalse(Lrl(Two())(false));
     Assert.AreEqual(Optional <Optional <Void> > .Empty(), Rlr(Two())(Optional <Optional <Void> > .Empty()));
     Assert.AreEqual(Optional <Optional <Void> > .From(Optional <Void> .Empty()),
                     Rlr(Two())(Optional <Optional <Void> > .From(Optional <Void> .Empty())));
 }
 public void powTest()
 {
     Assert.AreEqual(Unit.INSTANCE, Rlr(PowO <Unit>())(Unit.INSTANCE));
     Assert.AreEqual("DA★ZE|DA★ZE|DA★ZE", Lrl(PowS <string, int>())(MaybeFunc)(Optional <int> .From(3)));
     Assert.AreEqual(str, Lrl(PowS <string, int>())(MaybeFunc)(Optional <int> .Empty()));
     Assert.AreEqual(str, Rlr(PowS <string, int>())(Tuple.Create <string, Func <int, string> >(str, FuncIntStr)).Item1);
     Assert.AreEqual("DA★ZE|DA★ZE|DA★ZE",
                     Rlr(PowS <string, int>())(Tuple.Create <string, Func <int, string> >(str, FuncIntStr)).Item2(3));
     Assert.AreEqual(str, Lrl(PowSO <string>())(unit => str)(Unit.INSTANCE));
     Assert.AreEqual(str, Rlr(PowSO <string>())(str));
     Assert.AreEqual(str, Lrl(PowSO_ <string>())(unit => str)(Unit.INSTANCE));
     Assert.AreEqual(str, Rlr(PowSO_ <string>())(str));
 }
    public void DistTest()
    {
        var tuple = new Tuple <int, Either <bool, string> >(0, Either <bool, string> .Left(true));

        Assert.AreEqual(tuple, Lrl(Dist <int, bool, string>())(tuple));
        var tuple2 = new Tuple <int, Either <bool, string> >(0, Either <bool, string> .Right(str));

        Assert.AreEqual(tuple2, Lrl(Dist <int, bool, string>())(tuple2));
        var either = Either <Tuple <int, bool>, Tuple <int, string> > .Left(new Tuple <int, bool>(0, true));

        Assert.AreEqual(either, Rlr(Dist <int, bool, string>())(either));
        var either2 = Either <Tuple <int, bool>, Tuple <int, string> > .Right(new Tuple <int, string>(0, str));

        Assert.AreEqual(either2, Rlr(Dist <int, bool, string>())(either2));
    }
    public void multTest()
    {
        var val = new Random(DateTime.Now.Millisecond).Next();

        Assert.AreEqual(Tuple.Create(Optional <string> .From(str), val),
                        Lrl(MultS <string, int>())(Tuple.Create(Optional <string> .From(str), val)));
        Assert.AreEqual(Tuple.Create(Optional <string> .Empty(), val),
                        Lrl(MultS <string, int>())(Tuple.Create(Optional <string> .Empty(), val)));
        Assert.AreEqual(Either <int, Tuple <string, int> > .Left(val),
                        Rlr(MultS <string, int>())(Either <int, Tuple <string, int> > .Left(val)));
        Assert.AreEqual(Either <int, Tuple <string, int> > .Right(Tuple.Create(str, val)),
                        Rlr(MultS <string, int>())(Either <int, Tuple <string, int> > .Right(Tuple.Create(str, val))));
        Assert.AreEqual(Tuple.Create(Unit.INSTANCE, true), Lrl(MultSO <bool>())(Tuple.Create(Unit.INSTANCE, true)));
        Assert.AreEqual(Tuple.Create(Unit.INSTANCE, false), Lrl(MultSO <bool>())(Tuple.Create(Unit.INSTANCE, false)));
        Assert.IsTrue(Rlr(MultSO <bool>())(true));
        Assert.IsFalse(Rlr(MultSO <bool>())(false));
    }
    public void Assoc()
    {
        var val = new Random(DateTime.Now.Millisecond).Next();

        Assert.AreEqual(Either <Either <int, bool>, bool> .Left(Either <int, bool> .Left(val)),
                        Lrl(PlusAssoc <int, bool, bool>())(Either <Either <int, bool>, bool> .Left(Either <int, bool> .Left(val))));
        Assert.AreEqual(Either <Either <int, bool>, bool> .Left(Either <int, bool> .Right(true)),
                        Lrl(PlusAssoc <int, bool, bool>())(Either <Either <int, bool>, bool> .Left(Either <int, bool> .Right(true))));
        Assert.AreEqual(Either <Either <int, bool>, string> .Right(str),
                        Lrl(PlusAssoc <int, bool, string>())(Either <Either <int, bool>, string> .Right(str)));
        Assert.AreEqual(Either <int, Either <bool, string> > .Left(val),
                        Rlr(PlusAssoc <int, bool, string>())(Either <int, Either <bool, string> > .Left(val)));
        Assert.AreEqual(Either <bool, Either <bool, string> > .Right(Either <bool, string> .Left(true)),
                        Rlr(PlusAssoc <bool, bool, string>())(Either <bool, Either <bool, string> > .Right(Either <bool, string> .Left(true))));
        Assert.AreEqual(Either <bool, Either <bool, string> > .Right(Either <bool, string> .Right(str)),
                        Rlr(PlusAssoc <bool, bool, string>())(Either <bool, Either <bool, string> > .Right(Either <bool, string> .Right(str))));
    }
 public void OneTest()
 {
     Assert.AreEqual(Unit.INSTANCE, Lrl(One())(Unit.INSTANCE));
     Assert.AreEqual(Optional <Void> .Empty(), Rlr(One())(Optional <Void> .Empty()));
 }
 public void CurryTest()
 {
     Assert.AreEqual(Cul(0, true), Lrl(CurryISO <int, bool, string>())(a => b => Cul(a, b))(0)(true));
     Assert.AreEqual(Cul(0, true), Rlr(CurryISO <int, bool, string>())(Cur)(new Tuple <int, bool>(0, true)));
 }