public static IMorphism <TSource, TResult, DotNet> o <TSource, TMiddle, TResult>( this IMorphism <TMiddle, TResult, DotNet> m2, IMorphism <TSource, TMiddle, DotNet> m1) { Argument.Requires(m2.Category == m1.Category, $"{nameof(m2)} and {nameof(m1)} are not in the same category."); return(m1.Category.o(m2, m1)); }
/// <summary> /// Returns a composition of the two morphisms. /// </summary> public static IMorphism <A, C> Compose <A, B, C>(IMorphism <A, B> m1, IMorphism <B, C> m2) { var mappings = m1.Domain.Select(a => { var bo = m1.Apply(a); var co = bo.FlatMap(b => m2.Apply(b)); return(co.Map(c => Product2.Create(a, c))); }); return(Create(mappings.Flatten())); }
public IMorphism <TSource, TResult, IMonoid <T> > o <TSource, TMiddle, TResult>( IMorphism <TMiddle, TResult, IMonoid <T> > m2, IMorphism <TSource, TMiddle, IMonoid <T> > m1) { if (!(typeof(T).IsAssignableFrom(typeof(TSource)) && typeof(T).IsAssignableFrom(typeof(TMiddle)) && typeof(T).IsAssignableFrom(typeof(TResult)))) { throw new InvalidOperationException($"Category {nameof(Monoid<T>)} has only 1 object {nameof(T)}."); } return(new MonoidMorphism <T>( this, _ => this.Binary( (T)(object)m1.Invoke((TSource)(object)this.Unit), (T)(object)m2.Invoke((TMiddle)(object)this.Unit))) as IMorphism <TSource, TResult, IMonoid <T> >); }
public void EnumerableGeneralTest() { IEnumerable <int> functor = new int[] { 0, 1, 2 }; Func <int, int> addOne = x => x + 1; // Functor law 1: F.Select(Id) == Id(F) EnumerableAssert.AreSequentialEqual(functor.Select(Functions.Id), Functions.Id(functor)); // Functor law 2: F.Select(f2.o(f1)) == F.Select(f1).Select(f2) Func <int, string> addTwo = x => (x + 2).ToString(CultureInfo.InvariantCulture); IMorphism <int, int, DotNet> addOneMorphism = addOne.DotNetMorphism(); IMorphism <int, string, DotNet> addTwoMorphism = addTwo.DotNetMorphism(); EnumerableAssert.AreSequentialEqual( addTwoMorphism.o(addOneMorphism).Select().Invoke(functor), addTwoMorphism.Select().o(addOneMorphism.Select()).Invoke(functor)); }
public IMorphism <TSource, TResult, DotNet> o <TSource, TMiddle, TResult> (IMorphism <TMiddle, TResult, DotNet> m2, IMorphism <TSource, TMiddle, DotNet> m1) => new DotNetMorphism <TSource, TResult>(@object => m2.Invoke(m1.Invoke(@object)));
public static IMorphism <Lazy <TSource1, TSource2>, Lazy <TResult1, TResult2>, DotNet> Select <TSource1, TSource2, TResult1, TResult2> (IMorphism <TSource1, TResult1, DotNet> selector1, IMorphism <TSource2, TResult2, DotNet> selector2) => new DotNetMorphism <Lazy <TSource1, TSource2>, Lazy <TResult1, TResult2> >( source => source.Select(selector1.Invoke, selector2.Invoke));
// General abstract functor definition of Tuple<>: DotNet -> DotNet. public static IMorphism <Tuple <TSource>, Tuple <TResult>, DotNet> Select <TSource, TResult> (/* this */ IMorphism <TSource, TResult, DotNet> selector) => new DotNetMorphism <Tuple <TSource>, Tuple <TResult> >(source => source.Select(selector.Invoke));
// General abstract functor definition for IEnumerable<>: DotNet -> DotNet. public static IMorphism <IEnumerable <TSource>, IEnumerable <TResult>, DotNet> Select <TSource, TResult> (this IMorphism <TSource, TResult, DotNet> selector) => new DotNetMorphism <IEnumerable <TSource>, IEnumerable <TResult> >(source => source.Select(selector.Invoke));