观察同构,然后将它们证明为Monad

时间:2014-05-27 19:21:06

标签: haskell monads

此问题与此answer有关。

有一个名为Promise的类型:

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

据说:

Promise f a ≅ Maybe (Either f a)

现在我无法理解上面的表达方式。他们怎么样 等价和同构(从那你怎么能得出它的结论 是Monad)?

4 个答案:

答案 0 :(得分:11)

如果有AB这两个函数a2b :: A -> Bb2a :: B -> A,则a2b . b2a ≡ idb2a . 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的值可以是三个不同的东西:

  1. 类型f的值,带有构造函数PendingPromise
  2. 类型a的值,包含构造函数ResolvedPromis
  3. 或没有值,使用构造函数BrokenPromise
  4. 同样,Maybe (Either f a)的值可以是三件事:

    1. 类型为f的值,其中包含&#39;构造函数&#39; Just . Left
    2. 类型为a的值,其中包含&#39;构造函数&#39; Just . Right
    3. 没有值,使用构造函数Nothing
    4. 因此在这个意义上,类型是同构的。在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

鉴于MaybeEither都是Monad的实例,Promise可能会被表示为monad。

可能的实施可能是:

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

Live demo

答案 3 :(得分:1)

Maybe (Either f a)有三种可能性:

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

这与Promise f a同构。

这也与

相同
EitherT f (Maybe a)

也是一个单子。