Two types A and B isomorphic if there are two functions a2b :: A -> B and b2a :: B -> A such that a2b . b2a ≡ id a2b . b2a ≡ id and b2a . a2b ≡ id b2a . a2b ≡ id . This is easy to prove in this example: the two functions have basically the same sentences as the = sides turned around, for example,
promise2Trafo (PendingPromise f) = ErrorT . Just $ Left f trafo2Promise (ErrorT (Just (Left f))) = PendingPromise f
therefore compiling functions in any order gives you an identity function. The most important feature of isomorphism is that a2b x ≡ a2b y holds exactly if f x ≡ y .
Now, how does this help prove the laws of styles? Again taken from the example,
instance Applicative Promise where pure = trafo2Promise . pure fp <*> xp = trafo2Promise $ promise2Trafo fp <*> promise2Trafo xp
Now we need to prove, among other things,
pure id <*> xp ≡ xp
Instead of doing it manually, we use the fact that this law has already been proved for ErrorT f Maybe a , so we just introduce some identities:
trafo2Promise $ promise2Trafo (trafo2Promise $ pure id) <*> promise2Trafo xp ≡ trafo2Promise $ pure id <*> promise2Trafo xp
which is ≡ promise2Trafo xp iff pure id <*> promise2Trafo xp ≡ promise2Trafo xp , which, as we know, is true.
source share