Наблюдение изоморфизма, а затем доказательство их как монады
этот вопрос связан с этим ответ.
существует тип с именем 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
может быть три разных вещи:
- значение типа
f
, с конструкторомPendingPromise
. - значение типа
a
, С конструкторомResolvedPromis
, - или нет значения, с конструктором
BrokenPromise
.
аналогично, стоимостью Maybe (Either f a)
может быть три вещи:
- значение типа
f
, С 'constructor'Just . Left
. - значение типа
a
, С 'конструктор'Just . Right
. - нет значения, с конструктором
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
есть три possiblilities для Maybe (Either f a)
:
Just (Left f) | Just (Right a) | Nothing
это изоморфно to Promise f a
.
Это также то же самое, что
EitherT f (Maybe a)
, который также является монадой.