问题
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:
- A value of type
f
, with constructorPendingPromise
. - A value of type
a
, with constructorResolvedPromis
, - or no value, with constructor
BrokenPromise
.
Similarly, a value of Maybe (Either f a)
can be three things:
- A value of type
f
, with 'constructor'Just . Left
. - A value of type
a
, with 'constructor'Just . Right
. - 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