public static bool TestFirstDistributivity()
        {
            var f = new Func<int, int>(x => x * 3 - 2);
            var g = new Func<int, int>(y => (y + 2) / 3);
            var id = new Func<int, int>(x => x);

            var unDistributed = f.Arr(g).First(default(int));

            var distributed = (f.Mult(id)).Arr(g.Mult(id));

            return ArrowTestUtils.AssertPairInvertibleArrowsGiveSameOutput(distributed, unDistributed);
        }
        public static bool TestCompositionDistributivity()
        {
            var f1 = new Func<int, int>(x => x * 2);
            var f2 = new Func<int, int>(x => x - 1);
            var g1 = new Func<int, int>(x => x / 2);
            var g2 = new Func<int, int>(x => x + 1);

            var undistributed = f1.Arr(g1).Combine(f2.Arr(g2));
            var distributed = new Func<int, int>(x => f2(f1(x)))
                                .Arr(new Func<int, int>(y => g1(g2(y))));

            return ArrowTestUtils.AssertInvertibleArrowsGiveSameOutput(undistributed, distributed);
        }
        public static bool TestInversionCorrectness()
        {
            var f = new Func<int, int>(x => x * 3);
            var g = new Func<int, int>(y => y / 3);

            var inverted = f.Arr(g).Invert();
            var actuallyInverse = g.Arr(f);

            return ArrowTestUtils.AssertInvertibleArrowsGiveSameOutput(inverted, actuallyInverse);
        }