此问题与此answer有关。
有一个名为Promise
的类型:
data Promise f a = PendingPromise f | ResolvedPromise a | BrokenPromise deriving (Show)
据说:
Promise f a ≅ Maybe (Either f a)
现在我无法理解上面的表达方式。他们怎么样 等价和同构(从那你怎么能得出它的结论 是Monad)?
答案 0 :(得分:11)
如果有A
和B
这两个函数a2b :: A -> B
和b2a :: B -> A
,则a2b . b2a ≡ id
和b2a . a2b ≡ id
两种类型是同构的。在这个例子中,这很容易证明:这两个函数基本上具有相同的子句,其中=
的边转过来,例如。
promise2Trafo (PendingPromise f) = ErrorT . Just $ Left f
trafo2Promise (ErrorT (Just (Left f))) = PendingPromise f
所以按任意顺序编写函数会给你一个身份函数。关于同构的关键是a2b x ≡ a2b y
完全保存iff x ≡ y
。
现在,这有助于证明类型规律?再次从示例中获取,
instance Applicative Promise where
pure = trafo2Promise . pure
fp <*> xp = trafo2Promise $ promise2Trafo fp <*> promise2Trafo xp
现在我们需要证明其他事项
pure id <*> xp ≡ xp
我们不是手工执行此操作,而是利用这一法律已经在ErrorT f Maybe a
得到证明的事实,因此我们只是介绍一些身份:
trafo2Promise $ promise2Trafo (trafo2Promise $ pure id) <*> promise2Trafo xp
≡ trafo2Promise $ pure id <*> promise2Trafo xp
≡ promise2Trafo xp
iff pure id <*> promise2Trafo xp ≡ promise2Trafo xp
,我们知道这是真的。
答案 1 :(得分:8)
类型Promise f a
的值可以是三个不同的东西:
f
的值,带有构造函数PendingPromise
。a
的值,包含构造函数ResolvedPromis
,BrokenPromise
。同样,Maybe (Either f a)
的值可以是三件事:
f
的值,其中包含&#39;构造函数&#39; Just . Left
。a
的值,其中包含&#39;构造函数&#39; Just . Right
。Nothing
。因此在这个意义上,类型是同构的。在Haskell中这不是很正确的原因与undefined
值(底部)有关,但你可以忽略它们以使生活更轻松。
Maybe (Either f a)
也可以被视为EitherT f (Maybe a)
,这是Monad
的一个实例。
答案 2 :(得分:2)
您可以轻松地将Promise f a
映射到Maybe (Either f a)
,如下所示:
PendingPromise f -> Just (Left f)
ResolvedPromise a -> Just (Right a)
BrokenPromise -> Nothing
鉴于Maybe
和Either
都是Monad
的实例,Promise
可能会被表示为monad。
可能的实施可能是:
instance Monad (Promise f) where
return a = ResolvedPromise a
BrokenPromise >>= _ = BrokenPromise
PendingPromise a >>= _ = PendingPromise a
ResolvedPromise a >>= f = f a
答案 3 :(得分:1)
Maybe (Either f a)
有三种可能性:
Just (Left f) | Just (Right a) | Nothing
这与Promise f a
同构。
这也与
相同EitherT f (Maybe a)
也是一个单子。