// public static ISO<Either<L, R>, Either<R, L>> IsoEither<L, R>() => // new ISO<Either<L, R>, Either<R, L>>( // lr => lr.Match<Either<R, L>>(Either<R, L>.Right, Either<R, L>.Left), // rl => rl.Match<Either<L, R>>(Either<L, R>.Right, Either<L, R>.Left)); public static ISO <Either <A, C>, Either <B, D> > IsoEither <A, B, C, D>(ISO <A, B> ab, ISO <C, D> cd) { return(new ISO <Either <A, C>, Either <B, D> > (l => l.Match <Either <B, D> >(a => Either <B, D> .Left(ab.Fw(a)), c => Either <B, D> .Right(cd.Fw(c))), r => r.Match <Either <A, C> >(b => Either <A, C> .Left(ab.Bw(b)), d => Either <A, C> .Right(cd.Bw(d))))); }
public static ISO <Func <A, C>, Func <B, D> > IsoFunc <A, B, C, D>(ISO <A, B> ab, ISO <C, D> cd) { return(new ISO <Func <A, C>, Func <B, D> > (ac => a => cd.Fw(ac(ab.Bw(a))), bd => b => cd.Bw(bd(ab.Fw(b))))); }
// where (), the empty tuple, has 1 value, and Void has 0 value // If we have isoUnEither, // We have ISO () Void by calling isoUnEither isoEU // That is impossible, since we can get a Void by // substL on ISO () Void // So it is impossible to have isoUnEither /// Going another way is hard (and is generally impossible) /// Remember, for all valid ISO, converting and converting back /// is the same as the original value. /// You need this to prove some case are impossible. public static ISO <A, B> IsoUnOptional <A, B>(ISO <Optional <A>, Optional <B> > iso) { return(new ISO <A, B> (a => iso.Fw(Optional <A> .From(a)).OrElseGet(() => iso.Fw(Optional <A> .Empty()).Get()), b => iso.Bw(Optional <B> .From(b)).OrElseGet(() => iso.Bw(Optional <B> .Empty()).Get()))); }
public static ISO <List <A>, List <B> > IsoList <A, B>(ISO <A, B> iso) { return(new ISO <List <A>, List <B> > (a => a.ConvertAll(i => iso.Fw(i)), b => b.ConvertAll(i => iso.Bw(i)))); }
/// we can combine isomorphism public static ISO <Tuple <A, C>, Tuple <B, D> > IsoTuple <A, B, C, D>(ISO <A, B> ab, ISO <C, D> cd) { return(new ISO <Tuple <A, C>, Tuple <B, D> > (ac => Tuple.Create(ab.Fw(ac.Item1), cd.Fw(ac.Item2)), bd => Tuple.Create(ab.Bw(bd.Item1), cd.Bw(bd.Item2)))); }
/// isomorphism is transitive public static ISO <A, C> Trans <A, B, C>(ISO <A, B> ab, ISO <B, C> bc) { return(new ISO <A, C>(a => bc.Fw(ab.Fw(a)), c => ab.Bw(bc.Bw(c)))); }
private static Func <B, B> Rlr <A, B>(ISO <A, B> Iso) { return(it => Iso.Fw(Iso.Bw(it))); }
private static Func <A, A> Lrl <A, B>(ISO <A, B> Iso) { return(it => Iso.Bw(Iso.Fw(it))); }
private static Func <B, B> rlr <A, B>(ISO <A, B> Iso) => it => Iso.Fw(Iso.Bw(it));
private static Func <A, A> lrl <A, B>(ISO <A, B> Iso) => it => Iso.Bw(Iso.Fw(it));