Наблюдение изоморфизма, а затем доказательство их как монады

этот вопрос связан с этим ответ.

существует тип с именем Promise:

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

установлено, что:

Promise f a ≅ Maybe (Either f a)
Я не могу понять приведенное выше выражение. Как они эквивалентно и изоморфно (и из этого как вы можете заключить, что это это монада) ?

4 ответов


два типа 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, что, как мы знаем, верно.


значение типа Promise f a может быть три разных вещи:

  1. значение типа f, с конструктором PendingPromise.
  2. значение типа a, С конструктором ResolvedPromis,
  3. или нет значения, с конструктором BrokenPromise.

аналогично, стоимостью Maybe (Either f a) может быть три вещи:

  1. значение типа f, С 'constructor'Just . Left.
  2. значение типа a, С 'конструктор' Just . Right.
  3. нет значения, с конструктором Nothing.

таким образом, в этом смысле типы изоморфны. Причина, по которой это не совсем верно в Haskell, связана с undefined значения (днища), но вы можете игнорировать их, чтобы облегчить жизнь.

Maybe (Either f a) также можно рассматривать как EitherT f (Maybe a), который является экземпляром Monad.


вы можете легко сопоставить Promise f a до Maybe (Either f a) следующим образом:

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

учитывая, что оба Maybe и Either экземпляров Monad, возможно Promise выражаться как монада.

возможной реализацией может быть:

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

Live demo


есть три possiblilities для Maybe (Either f a):

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

это изоморфно to Promise f a.

Это также то же самое, что

EitherT f (Maybe a)

, который также является монадой.