# Control.Isomorphism

record Iso a b

  An isomorphism between two types

  a
  b
  MkIso : (to : a -> b) -> (from : b -> a) -> (toFrom : (y : b) -> to (from y) = y) -> (fromTo : (x : a) -> from (to x) = x) -> Iso a b
  to : (rec : Iso a b) -> a -> b
  from : (rec : Iso a b) -> b -> a
  toFrom : (rec : Iso a b) -> (y : b) -> to rec (from rec y) = y
  fromTo : (rec : Iso a b) -> (x : a) -> from rec (to rec x) = x
MkIso : (to : a -> b) -> (from : b -> a) -> (toFrom : (y : b) -> to (from y) = y) -> (fromTo : (x : a) -> from (to x) = x) -> Iso a b
distribLeft : Iso (Either a b, c) (Either (a, c) (b, c))

  Products distribute over sums

distribRight : Iso (a, Either b c) (Either (a, b) (a, c))

  Products distribute over sums

eitherAssoc : Iso (Either (Either a b) c) (Either a (Either b c))

  Disjunction is associative

eitherBotLeft : Iso (Either Void a) a

  Disjunction with false is a no-op

eitherBotRight : Iso (Either a Void) a

  Disjunction with false is a no-op

eitherComm : Iso (Either a b) (Either b a)

  Disjunction is commutative

eitherCong : Iso a a' -> Iso b b' -> Iso (Either a b) (Either a' b')

  Isomorphism is a congruence with regards to disjunction

eitherCongLeft : Iso a a' -> Iso (Either a b) (Either a' b)

  Isomorphism is a congruence with regards to disjunction on the left

eitherCongRight : Iso b b' -> Iso (Either a b) (Either a b')

  Isomorphism is a congruence with regards to disjunction on the right

eitherFinPlus : Iso (Either (Fin m) (Fin n)) (Fin (m + n))
eitherMaybeLeftMaybe : Iso (Either (Maybe a) b) (Maybe (Either a b))
eitherMaybeRightMaybe : Iso (Either a (Maybe b)) (Maybe (Either a b))
finPairTimes : Iso (Fin m, Fin n) (Fin (m * n))
finZeroBot : Iso (Fin (fromInteger 0)) Void
isoRefl : Iso a a

  Isomorphism is Reflexive

isoSym : Iso a b -> Iso b a

  Isomorphism is symmetric

isoTrans : Iso a b -> Iso b c -> Iso a c

  Isomorphism is transitive

maybeCong : Iso a b -> Iso (Maybe a) (Maybe b)

  Isomorphism is a congruence with respect to Maybe

maybeEither : Iso (Maybe a) (Either a ())

  `Maybe a` is the same as `Either a ()`

maybeIsoS : Iso (Maybe (Fin n)) (Fin (S n))
maybeVoidUnit : Iso (Maybe Void) ()

  Maybe of void is just unit

pairAssoc : Iso (a, b, c) ((a, b), c)

  Conjunction is associative

pairBotLeft : Iso (Void, a) Void

  Conjunction preserves falsehood

pairBotRight : Iso (a, Void) Void

  Conjunction preserves falsehood

pairComm : Iso (a, b) (b, a)

  Conjunction is commutative

pairCong : Iso a a' -> Iso b b' -> Iso (a, b) (a', b')

  Isomorphism is a congruence with regards to conjunction

pairCongLeft : Iso a a' -> Iso (a, b) (a', b)

  Isomorphism is a congruence with regards to conjunction on the left

pairCongRight : Iso b b' -> Iso (a, b) (a, b')

  Isomorphism is a congruence with regards to conjunction on the right

pairUnitLeft : Iso ((), a) a

  Conjunction with truth is a no-op

pairUnitRight : Iso (a, ()) a

  Conjunction with truth is a no-op

qed : (a : Type) -> Iso a a

  Used for preorder reasoning syntax. Not intended for direct use.

step : (a : Type) -> Iso a b -> Iso b c -> Iso a c

  Used for preorder reasoning syntax. Not intended for direct use.