Observing isomorphism and then proving them as Monad

风流意气都作罢 提交于 2019-12-10 13:17:52

问题


This question is related to this answer.

There is a type named Promise:

data Promise f a =  PendingPromise f | ResolvedPromise a | BrokenPromise deriving (Show)

It is stated that:

Promise f a ≅ Maybe (Either f a)

Now I cannot understand the above expression. How are they sort of equivalent and isomorphic (and from that how can you conclude that it is a Monad) ?


回答1:


Two types A and B are isomorphic if there's two functions a2b :: A -> B and b2a :: B -> A such that a2b . b2a ≡ id and b2a . a2b ≡ id. In the example this is easy to prove: the two functions have basically the same clauses with the sides of = turned around, e.g.

promise2Trafo (PendingPromise f) = ErrorT . Just $ Left f
trafo2Promise (ErrorT (Just (Left f))) = PendingPromise f

so composing the functions in either order gives you the identity function. The crucial thing about an isomorphism is that a2b x ≡ a2b y holds exactly iff x ≡ y.

Now, how does that help proving typeclass laws? Again taken from the example,

instance Applicative Promise where
  pure = trafo2Promise . pure
  fp <*> xp = trafo2Promise $ promise2Trafo fp <*> promise2Trafo xp

Now here we need to prove amongst other things

  pure id <*> xp ≡ xp

Instead of doing this by hand, we exploit the fact that this law has already been proven for ErrorT f Maybe a, so we simply 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 we know is true.




回答2:


A value of type Promise f a can be three different things:

  1. A value of type f, with constructor PendingPromise.
  2. A value of type a, with constructor ResolvedPromis,
  3. or no value, with constructor BrokenPromise.

Similarly, a value of Maybe (Either f a) can be three things:

  1. A value of type f, with 'constructor' Just . Left.
  2. A value of type a, with 'constructor' Just . Right.
  3. No value, with constructor Nothing.

So in that sense the types are isomorphic. The reason that this is not quite true in Haskell has to do with undefined values (bottoms), but you can ignore those to make life easier.

Maybe (Either f a) can also be seen as EitherT f (Maybe a), which is an instance of Monad.




回答3:


You can easily map a Promise f a to a Maybe (Either f a) as follows:

  • PendingPromise f -> Just (Left f)
  • ResolvedPromise a -> Just (Right a)
  • BrokenPromise -> Nothing

Given that both Maybe and Either are instances of Monad, it is possible for Promise to be expressed as a monad.

A possible implementation could be:

instance Monad (Promise f) where
    return a = ResolvedPromise a
    BrokenPromise >>= _ = BrokenPromise
    PendingPromise a >>= _ = PendingPromise a
    ResolvedPromise a >>= f = f a

Live demo




回答4:


There are three possiblilities for Maybe (Either f a):

Just (Left f) | Just (Right a) | Nothing

this is isomorphic to to Promise f a.

This is also the same as

EitherT f (Maybe a)

which is also a monad.



来源:https://stackoverflow.com/questions/23897317/observing-isomorphism-and-then-proving-them-as-monad

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!