Advertisement
Guest User

Full Code of Isomoprhism ISO Class Java

a guest
Aug 13th, 2017
336
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.57 KB | None | 0 0
  1. package newcodewarsgen;
  2.  
  3. import java.util.Optional;
  4. import java.util.function.Function;
  5. import java.util.stream.Stream;
  6. import java.util.List;
  7. import java.util.stream.Collectors;
  8.  
  9. /*
  10.  * so, when are two type, `a` and `b`, considered equal?
  11.  * a definition might be, it is possible to go from `a` to `b`,
  12.  * and from `b` to `a`.
  13.  * Going a roundway trip should leave you the same value.
  14.  * Unfortunately it is virtually impossible to test this in Haskell.
  15.  * This is called ISO.
  16.  */
  17. public abstract class ISO<A, B> {
  18.   /* go backward */
  19.   abstract A bw(final B b);
  20.  
  21.   /* go forward */
  22.   abstract B fw(final A a);
  23.  
  24.   abstract static class Either<L, R> {
  25.     public abstract <T> T pm(Function<L, T> lt, Function<R, T> rt);
  26.    
  27.     static <L, R> Either<L, R> left(L l) {
  28.       return new Either<L, R>() {
  29.         @Override
  30.         public <T> T pm(Function<L, T> lt, Function<R, T> rt) {
  31.           return lt.apply(l);
  32.         }
  33.        
  34.         @Override
  35.         public boolean equals(Object rhs) {
  36.           return ((Either<L, R>) rhs).<Boolean>pm(l::equals, rr -> false);
  37.         }
  38.        
  39.         @Override
  40.         public String toString() {
  41.           return "left: " + l.toString();
  42.         }
  43.       };
  44.     }
  45.  
  46.     static <L, R> Either<L, R> right(R r) {
  47.       return new Either<L, R>() {
  48.         @Override
  49.         public <T> T pm(Function<L, T> lt, Function<R, T> rt) {
  50.           return rt.apply(r);
  51.         }
  52.        
  53.         @Override
  54.         public boolean equals(Object rhs) {
  55.           return ((Either<L, R>) rhs).<Boolean>pm(ll -> false, r::equals);
  56.         }
  57.  
  58.         @Override
  59.         public String toString() {
  60.           return "right: " + r.toString();
  61.         }
  62.       };
  63.     }
  64.   }
  65.  
  66.   final static class Tuple<A, B> {
  67.     A a;
  68.     B b;
  69.  
  70.     Tuple(A a, B b) {
  71.       this.a = a;
  72.       this.b = b;
  73.     }
  74.    
  75.     @Override
  76.     public boolean equals(Object rhs) {
  77.       Tuple<A, B> ab = (Tuple<A, B>) rhs;
  78.       return a.equals(ab.a) && b.equals(ab.b);
  79.     }
  80.   }
  81.  
  82.   final static class Unit {
  83.     public static Unit INSTANCE = new Unit();
  84.  
  85.     private Unit() {
  86.     }
  87.   }
  88.  
  89.   static abstract class Void {
  90.     public abstract <T> T absurd();
  91.   }
  92.  
  93.   private static <A, B> ISO<A, B> iso(
  94.     Function<A, B> forward, Function<B, A> backward) {
  95.     return new ISO<A, B>() {
  96.       @Override public A bw(B b) { return backward.apply(b); }
  97.       @Override public B fw(A a) { return forward.apply(a); }
  98.     };
  99.   }
  100.  
  101.   /* given ISO a b, we can go from a to b */
  102.   static <A, B> Function<A, B> subStL(final ISO<A, B> iso) {
  103.     return iso::fw;
  104.   }
  105.  
  106.   /* and vise versa */
  107.   static <A, B> Function<B, A> subStR(final ISO<A, B> iso) {
  108.     return iso::bw;
  109.   }
  110.  
  111.   /* There can be more than one ISO a b */
  112.   static ISO<Boolean, Boolean> isoBool() {
  113.     return refl();
  114.   }
  115.  
  116.   static ISO<Boolean, Boolean> isoBoolNot() {
  117.     return iso(a -> !a, b -> !b);
  118.   }
  119.  
  120.   /* isomorphism is reflexive */
  121.   static <A> ISO<A, A> refl() {
  122.     return iso(a -> a, b -> b);
  123.   }
  124.  
  125.   /* isomorphism is symmetric */
  126.   static <A, B> ISO<A, B> symm(final ISO<B, A> iso) {
  127.     return iso(iso::bw, iso::fw);
  128.   }
  129.  
  130.   /* isomorphism is transitive */
  131.   static <A, B, C> ISO<A, C> trans(
  132.     final ISO<A, B> ab, final ISO<B, C> bc) {
  133.       return iso(a->{
  134.           a.toString();
  135.           return bc.fw(ab.fw(a));}, b->{
  136.               b.toString();
  137.               return ab.bw(bc.bw(b));
  138.                   });
  139. //    return iso(a -> bc.fw(ab.fw(a)), c -> ab.bw(bc.bw(c)));
  140.   }
  141.  
  142.   /* We can combine isomorphism */
  143.   static <A, B, C, D> ISO<Tuple<A, C>, Tuple<B, D>> isoTuple(
  144.     final ISO<A, B> ab, final ISO<C, D> cd) {
  145.     return iso(
  146.       ac -> new Tuple<>(ab.fw(ac.a), cd.fw(ac.b)),
  147.       bd-> new Tuple<>(ab.bw(bd.a), cd.bw(bd.b)));
  148. //      bd -> new Tuple<>(ab.bw(bd.a), cd.bw(bd.b)));
  149.   }
  150.  
  151.   static <A, B> ISO<Stream<A>, Stream<B>> isoStream(
  152.     final ISO<A, B> iso) {
  153.     return iso(as -> as.map(iso::fw), bs -> bs.map(iso::bw));
  154.   }
  155.  
  156.   static <A, B> ISO<Optional<A>, Optional<B>> isoOptional(
  157.     final ISO<A, B> iso) {
  158.     return iso(a -> a.map(iso::fw), b -> b.map(iso::bw));
  159.   }
  160.  
  161.   static <A, B, C, D> ISO<Either<A, C>, Either<B, D>> isoEither(
  162.     final ISO<A, B> ab, final ISO<C, D> cd) {
  163. //      return iso(ac -> ac.<Either<B, D>>pm(a -> Either.<B, D>left(ab.fw(a)), c -> Either.<B, D>right(cd.fw(c))),
  164. //        bd -> bd.<Either<A, C>>pm(b -> Either.<A, C>left(ab.bw(b)), d -> Either.<A, C>right(cd.bw(d))));
  165.     return iso(
  166.       l -> l.pm(
  167.         a -> Either.left(ab.fw(a)),
  168.         c  -> Either.right(cd.fw(c))),
  169.       r -> r.pm(
  170.         b -> Either.left(ab.bw(b)),
  171.         d -> Either.right(cd.bw(d))));
  172.   }
  173.  
  174.   /*
  175.    * Going another way is hard (and is generally impossible)
  176.    * Remember, for all valid ISO, converting and converting back
  177.    * is the same as the original value.
  178.    * You need this to prove some case are impossible.
  179.    */
  180.   static <A, B> ISO<A, B> isoUnOptional(
  181.     final ISO<Optional<A>, Optional<B>> iso) {
  182.     return iso(
  183.       a -> iso.fw(Optional.of(a))
  184.             .orElseGet(() -> iso.fw(Optional.empty()).get()),
  185.       b -> iso.bw(Optional.of(b))
  186.             .orElseGet(() -> iso.bw(Optional.empty()).get()));
  187.   }
  188.  
  189.   // We cannot have
  190.   // isoUnEither ::
  191.   // ISO (Either a b) (Either c d) -> ISO a c -> ISO b d.
  192.   // Note that we have
  193.   static ISO<Either<Stream<Unit>, Unit>, Either<Stream<Unit>, Void>>
  194.     isoEU() {
  195.     return iso(
  196.       l -> l.pm(
  197.         ll -> Either.left(Stream.concat(Stream.of(Unit.INSTANCE), ll)),
  198.         r -> Either.left(Stream.empty())),
  199.       r -> r.pm(
  200.         l -> {
  201.           List<Unit> lu = l.collect(Collectors.toList());
  202.         return lu.isEmpty() ?
  203.           Either.right(Unit.INSTANCE) :
  204.           Either.left(Stream.generate(() ->
  205.             Unit.INSTANCE).limit(lu.size() - 1)); },
  206.         Void::absurd));
  207.     }
  208.   // where (), the empty tuple, has 1 value, and Void has 0 value
  209.   // If we have isoUnEither,
  210.   // We have ISO () Void by calling isoUnEither isoEU
  211.   // That is impossible, since we can get a Void by
  212.   // substL on ISO () Void
  213.   // So it is impossible to have isoUnEither
  214.  
  215.   static <A, B, C, D> ISO<Function<A, C>, Function<B, D>>
  216.     isoFunc(final ISO<A, B> ab, final ISO<C, D> cd) {
  217.     return iso(
  218.         ac -> a -> cd.fw(ac.apply(ab.bw(a))),
  219.         bd -> b -> cd.bw(bd.apply(ab.fw(b))));    
  220. //      ac -> a -> cd.fw(ac.apply(ab.bw(a))),
  221. //      bd -> b -> cd.bw(bd.apply(ab.fw(b))));
  222.   }
  223.  
  224.   /* And we have isomorphism on isomorphism! */
  225.   static <A, B> ISO<ISO<A, B>, ISO<B, A>> isoSymm() {
  226.     return iso(ISO::symm, ISO::symm);
  227.   }
  228. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement