public static void RunSimpleInvertibleDemo() { Source source = new Source(); Destination dest = new Destination(); InvertibleArrow <int, int> arr = Op.Arr((int x) => x + 1, (int x) => x - 1); BindingsManager.CreateBinding(source.GetBindPoint("source"), arr, dest.GetBindPoint("result")); bool passed = true; Random rand = new Random(); for (int i = 0; i < 100; i++) { int next = rand.Next(); source.source = next; if (dest.result != next + 1) { passed = false; } dest.result -= 1; if (source.source != next - 1) { passed = false; } } if (passed) { Console.WriteLine("Invertible works too!"); } else { Console.WriteLine("Invertible doesn't work tho D:"); } }
public TwoWayMultiBinding(List <BindPoint> sources, InvertibleArrow <T1, T2> arrow, List <BindPoint> destinations) : base(sources, arrow, destinations) { this.reverseArrow = arrow.Invert(); SubscribeToSources(); SubscribeToDestinations(); }
First <A, B, C>(this InvertibleArrow <A, B> arr, C nullArgument) { /* * Version of First which has an unused parameter passed in to allow it to infer the * unknown third type. */ return(arr.First <A, B, C>()); }
public static Arrow <A, Tuple <B, B> > Split <A, B>(this InvertibleArrow <A, B> arr) { /* * Takes an invertible arrow from A to B and returns one with its output duplicated * into a tuple (overrides the usual version of this for normal Arrows so that Fanout * will work for invertible arrows without modification). */ InvertibleArrow <B, Tuple <B, B> > splitArrow = InvertibleSplit <B>(); return(arr.Combine(splitArrow)); }
public static void DemoInvertibleArrows() { Console.WriteLine("\t-- Invertible arrows demo --\n"); InvertibleArrow <int, int> arrow = Op.ArrowFunc((int x) => x * 2 + 5).Arr((int y) => (y - 5) / 2); InvertibleArrow <int, string> arrow2 = Op.ArrowFunc((int x) => x.ToString()).Arr((string y) => Convert.ToInt32(y)); InvertibleArrow <int, string> arrow3 = arrow.Combine(arrow2); string result = arrow3.Invoke(3); Console.WriteLine("3 into the arrow gives {0}", result); Console.WriteLine("{0} into the inverted arrow gives {1}", result, arrow3.Invert().Invoke(result)); }
Combine <A, B, C>(this InvertibleArrow <A, B> a1, InvertibleArrow <B, C> a2) { /* * Combine two invertible arrows end-to-end */ InvertibleArrow <B, A> a1Reversed = a1.Invert(); InvertibleArrow <C, B> a2Reversed = a2.Invert(); InvertibleArrow <A, C> result = new InvertibleArrow <A, C>( x => a2.Invoke(a1.Invoke(x)), x => a1Reversed.Invoke(a2Reversed.Invoke(x)) ); return(result); }
First <A, B, C>(this InvertibleArrow <A, B> arr) { /* * Similar to the First function for normal arrows, but obviously performing it on * InvertibleArrows instead. */ InvertibleArrow <B, A> reversed = arr.Invert(); return(new InvertibleArrow <Tuple <A, C>, Tuple <B, C> >( (Tuple <A, C> x) => new Tuple <B, C>( arr.Invoke(x.Item1), x.Item2 ), (Tuple <B, C> x) => new Tuple <A, C>( reversed.Invoke(x.Item1), x.Item2 ) )); }
public static bool AssertInvertibleArrowsGiveSameOutput <A, B>(InvertibleArrow <A, B> arr1, InvertibleArrow <A, B> arr2) { return(AssertArrowsGiveSameOutput(arr1, arr2) && AssertArrowsGiveSameOutput(arr1.Invert(), arr2.Invert())); }