継続モナドを左と右の随伴に因数分解する方法は?


11

状態モナドは積(左-ファンクター)とリーダー(右-表現可能)に因数分解できます。

  1. 継続モナドを因数分解する方法はありますか?以下のコードは、チェックを入力しない私の試みです
-- To form a -> (a -> k) -> k
{-# LANGUAGE MultiParamTypeClasses, TypeOperators, InstanceSigs, TypeSynonymInstances #-}
type (<-:) o i = i -> o
-- I Dont think we can have Functor & Representable for this type synonym

class Isomorphism a b where
   from :: a -> b
   to :: b -> a

instance Adjunction ((<-:) e) ((<-:) e) where
   unit :: a -> (a -> e) -> e
   unit a handler = handler a

   counit :: (a -> e) -> e -> a
   counit f e = undefined -- If we have a constraint on Isomorphism a e then we can implement this
  1. モナドを形成するLeft&Rights Adjointsのリストはありますか?

  2. 私は、2つの随伴が与えられると、それらは一意のモナドとコモナドを形成することを読みましたが、モナドが与えられると、複数の因数に因数分解できます。この例はありますか?

回答:


11

クラスAdjunctionは補助関数の小さなサブセットのみを表すため、型チェックは行われません。両方のファンクターはHaskの内部ファンクターです。

結局のところ、これは補助の場合には当てはまりません(<-:) r -| (<-:) r。ここには微妙に異なる2つのファンクタがあります。

  • f = (<-:) r、HaskからOp(Hask)へのファンクタ(Haskの反対のカテゴリ、Hask ^ opとも呼ばれる)
  • g = (<-:) r、Op(Hask)からHaskへのファンクター

特に、counit矢印は反転するOp(Hask)カテゴリの自然な変換である必要があります。

unit   :: a -> g (f a)
counit :: f (g a) <-: a

実際にcounitunit、この補助で一致します。

これを正しくキャプチャするには、FunctorAdjunctionクラスを一般化して、異なるカテゴリ間の付属物をモデル化できるようにする必要があります。

class Exofunctor c d f where
  exomap :: c a b -> d (f a) (f b)

class
  (Exofunctor d c f, Exofunctor c d g) =>
  Adjunction
    (c :: k -> k -> Type)
    (d :: h -> h -> Type)
    (f :: h -> k)
    (g :: k -> h) where
  unit :: d a (g (f a))
  counit :: c (f (g a)) a

次に、それはComposeモナド(そして、付加を反転させればコモナド)になります。

newtype Compose f g a = Compose { unCompose :: f (g a) }
adjReturn :: forall c f g a. Adjunction c (->) f g => a -> Compose g f a
adjReturn = Compose . unit @_ @_ @c @(->)

adjJoin :: forall c f g a. Adjunction c (->) f g => Compose g f (Compose g f a) -> Compose g f a
adjJoin = Compose . exomap (counit @_ @_ @c @(->)) . (exomap . exomap @(->) @c) unCompose . unCompose

そしてそれContは単にその特別なケースです:

type Cont r = Compose ((<-:) r) ((<-:) r)

詳細については、この要旨も参照してください。https//gist.github.com/Lysxia/beb6f9df9777bbf56fe5b42de04e6c64


一対の随伴が与えられると、それらはユニークなモナドとコモナドを形成するが、モナドが与えられると、それは複数の因子に因数分解できることを私は読んだ。この例はありますか?

因数分解は一般的に一意ではありません。上記のように付加を一般化したら、少なくとも任意のモナドMをそのKleisliカテゴリとそのベースカテゴリ(この場合はHask)の間の付加として因数分解できます。

Every monad M defines an adjunction
  F -| G
where

F : (->) -> Kleisli M
  : Type -> Type                -- Types are the objects of both categories (->) and Kleisli m.
                                -- The left adjoint F maps each object to itself.
  : (a -> b) -> (a -> M b)      -- The morphism mapping uses return.

G : Kleisli M -> (->)
  : Type -> Type                -- The right adjoint G maps each object a to m a
  : (a -> M b) -> (M a -> M b)  -- This is (=<<)

継続モナドがHaskの内部関数間の付加に対応しているかどうかはわかりません。

モナドに関するnCatLab記事も参照してください:https ://ncatlab.org/nlab/show/monad#RelationToAdjunctionsAndMonadicity

付属物とモナディシティとの関係

すべての付加(L⊣R)は、モナドR∘LおよびコモナードL∘Rを誘発します。一般に、この方法で特定のモナドを生成する複数の付加がありますが、実際には、特定のモナドに付属のカテゴリがあります。そのカテゴリの最初のオブジェクトは、モナドのKleisliカテゴリの補助であり、最終オブジェクトは代数のEilenberg-Mooreカテゴリの補助です。(例えば、Borceux、vol。2、prop。4.2.2)後者は、モナディック付加と呼ばれます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.