public static bool TestLaw8() { /* * Tests that a split arrow commutes with the 'fst' function (which returns the first * element of a tuple), that is: * first f >>> arr fst = arr fst >>> f */ Arrow <int, int> f = Op.Arr(ArrowTestUtils.GenerateFunc()); Arrow <Tuple <int, int>, int> fstArrow = Op.Arr((Tuple <int, int> x) => x.Item1); Arrow <Tuple <int, int>, int> firstFArrFst = f.First(default(int)).Combine(fstArrow); Arrow <Tuple <int, int>, int> arrFstF = fstArrow.Combine(f); return(ArrowTestUtils.AssertPairToSingleArrowsGiveSameOutput(firstFArrFst, arrFstF)); }
public static bool TestLaw4() { /* * Tests that the arrow of a composed pair of functions is equal to the composition of * arrows made from the individual functions, ie: * arr (g · f) = arr f >>> arr g */ Func <int, int> f = ArrowTestUtils.GenerateFunc(); Func <int, int> g = ArrowTestUtils.GenerateFunc(); Arrow <int, int> arrowCompose = Op.Arr((int x) => g(f(x))); Arrow <int, int> composeArrows = Op.Arr(f).Combine(Op.Arr(g)); return(ArrowTestUtils.AssertArrowsGiveSameOutput(arrowCompose, composeArrows)); }
public static bool TestLaw3() { /* * Tests that (f.Combine(g)).Combine(h) = f.Combine(g.Combine(h)) * That is, arrow combination is associative */ Arrow <int, int> arrF = Op.Arr((int x) => (x * x) - 5); Arrow <int, int> arrG = Op.Arr((int x) => (x + 5) * 7); Arrow <int, int> arrH = Op.Arr((int x) => (x - 50) * x); Arrow <int, int> fgH = (arrF.Combine(arrG)).Combine(arrH); Arrow <int, int> fGH = arrF.Combine(arrG.Combine(arrH)); return(ArrowTestUtils.AssertArrowsGiveSameOutput(fgH, fGH)); }
public static bool TestArrOperatorDistributivity() { /* * Tests that the Arr operator distributes over function composition. * That is, g(f(x)) = (arr f) >>> (arr g) * We test this by comparing a lambda combination of two functions with their arrow * combination. */ Func <int, int> f = ArrowTestUtils.GenerateFunc(); Func <int, int> g = ArrowTestUtils.GenerateFunc(); Func <int, int> fg = (x => g(f(x))); Arrow <int, int> arr = Op.Arr(f).Combine(Op.Arr(g)); return(ArrowTestUtils.AssertArrowEqualsFunc(arr, fg)); }
public static bool TestLaw6() { /* * Tests that the First operator distributes over arrow composition * first (f >>> g) = first f >>> first g */ Arrow <int, int> f = Op.Arr(ArrowTestUtils.GenerateFunc()); Arrow <int, int> g = Op.Arr(ArrowTestUtils.GenerateFunc()); Arrow <Tuple <int, int>, Tuple <int, int> > firstOutside = f.Combine(g).First(default(int)); Arrow <Tuple <int, int>, Tuple <int, int> > firstDistributed = f.First(default(int)) .Combine(g.First(default(int))); return(ArrowTestUtils.AssertPairArrowsGiveSameOutput(firstOutside, firstDistributed)); }
public static bool TestPipingCommutativity() { /* * If an identity is merged with a second function to form an arrow, attaching it to a * piped function must be commutative. In code: * arr (id *** g) >>> first f = first f >>> arr (id *** g) * This is tested by constructing the two arrows and checking their outputs match. */ Arrow <int, int> f = Op.Arr(ArrowTestUtils.GenerateFunc()); Arrow <int, int> g = Op.Arr(ArrowTestUtils.GenerateFunc()); Arrow <Tuple <int, int>, Tuple <int, int> > mergeFirst = new IDArrow <int>().And(g).Combine(f.First(default(int))); Arrow <Tuple <int, int>, Tuple <int, int> > firstMerge = f.First(default(int)).Combine(new IDArrow <int>().And(g)); return(ArrowTestUtils.AssertPairArrowsGiveSameOutput(mergeFirst, firstMerge)); }
public static bool TestArrFirstOrderingIrrelevance() { /* * Tests that the First and Arr operators, used in conjunction, will have the same * effect regardless of ordering. That is: * arr (first f) = first (arr f) */ Func <int, int> f = ArrowTestUtils.GenerateFunc(); Arrow <Tuple <int, int>, Tuple <int, int> > arrFirst = Op.Arr( (Tuple <int, int> x) => Tuple.Create(f(x.Item1), x.Item2) ); Arrow <Tuple <int, int>, Tuple <int, int> > firstArr = Op.First(Op.Arr(f), default(int)); return(ArrowTestUtils.AssertPairArrowsGiveSameOutput(arrFirst, firstArr)); }
public static bool TestFirstOperatorDistributivity() { /* * Tests that the First operator distributes over function competition, ie: * first (f >>> g) = first f >>> first g * This test is done using two arrows on pairs, f and g */ Arrow <int, int> f = Op.Arr(ArrowTestUtils.GenerateFunc()); Arrow <int, int> g = Op.Arr(ArrowTestUtils.GenerateFunc()); Arrow <Tuple <int, int>, Tuple <int, int> > firstFG = Op.First(f.Combine(g), default(int)); Arrow <Tuple <int, int>, Tuple <int, int> > firstFfirstG = Op.First(f, default(int)).Combine(Op.First(g, default(int))); return(ArrowTestUtils.AssertPairArrowsGiveSameOutput(firstFG, firstFfirstG)); }
public static bool TestPipingReassociation() { /* * Tests the following thing: * first (first f) >>> arr assoc = arr assoc >>> first f * The code itself is probably more expressive than any explanation I could come up * with. */ Arrow <int, int> f = Op.Arr(ArrowTestUtils.GenerateFunc()); AssocArrow <int, int, int> assoc = new AssocArrow <int, int, int>(); Arrow <Tuple <Tuple <int, int>, int>, Tuple <int, Tuple <int, int> > > firstFirstArr = f.First(default(int)).First(default(int)) .Combine(assoc); Arrow <Tuple <Tuple <int, int>, int>, Tuple <int, Tuple <int, int> > > arrFirst = assoc.Combine(f.First(default(Tuple <int, int>))); return(ArrowTestUtils.AssertReassociationArrowsGiveSameOutput(firstFirstArr, arrFirst)); }