簡體   English   中英

與Haskell中常見的monad相對應的伴隨函子對是什么?

[英]What are the adjoint functor pairs corresponding to common monads in Haskell?

在類別理論中,monad可以用兩個伴隨的仿函數構造。 特別是,如果CD是類別而F:C - > DG:D - > C是伴隨函子,在某種意義上說是雙射

hom(FX,Y)= hom(X,GY)

對於C中的每個XD中的 Y ,則組合物G o F:C→C是單子。


可以通過固定類型b並取FG來給出一對這樣的伴隨函子

data F b a = F (a,b)
data G b a = G (b -> a)

instance Functor (F b) where
  fmap f (F (a,b)) = F (f a, b)

instance Functor (G b) where
  fmap f (G g) = G (f . g)

並且通過currying給出了hom-sets之間的雙射(模數構造函數):

iso1 :: (F b a -> c) -> a -> G b c
iso1 f = \a -> G $ \b -> f (F (a,b))

iso2 :: (a -> G b c) -> F b a -> c
iso2 g = \(F (a,b)) -> let (G g') = g a in g' b

在這種情況下相應的monad是

data M b a = M { unM :: b -> (a,b) }

instance Monad (M b) where
    return a    = M (\b -> (a,b))
    (M f) >>= g = M (\r -> let (a,r') = f r in unM (g r') a)

我不知道這個monad的名字應該是什么,除了它看起來像是一個讀者monad,它帶有一些可寫的信息( 編輯: dbaupp在評論中指出這是State monad 。)

所以State monad可以被“分解”為一對伴隨函子FG ,我們可以寫

State = G . F

到現在為止還挺好。


我現在正在試圖弄清楚如何將其他常見的monad分解為成對的伴隨函子 - 例如Maybe[]ReaderWriterCont - 但我無法弄清楚我們可以“成對的伴隨函子對”將它們分解為。

唯一的簡單情況似乎是Identity單子,它可以被分解成任何對函子FG使得F是逆G (在尤其,可以只取F = IdentityG = Identity )。

任何人都能解釋一下嗎?

您正在尋找的是Kleisli類別 最初開發它是為了表明每個monad都可以用兩個伴隨的仿函數構造。

問題是Haskell Functor不是通用函子,它是Haskell類中的endo-functor。 所以我們需要不同的東西(AFAIK)來表示其他類別之間的仿函數:

{-# LANGUAGE FunctionalDependencies, KindSignatures #-}
import Control.Arrow
import Control.Category hiding ((.))
import qualified Control.Category as C
import Control.Monad

class (Category c, Category d) => CFunctor f c d | f -> c d where
    cfmap :: c a b -> d (f a) (f b)

請注意,如果我們對cd都采用-> ,我們得到一個Haskell類的endo-functor,它只是fmap的類型:

cfmap :: (a -> b) -> (f a -> f b)

現在我們有明確的類型類,它表示兩個給定類別cd之間的仿函數,我們可以表示給定monad的兩個伴隨仿函數。 左邊的一個將對象a映射到a並將態射f映射到(return .) f

-- m is phantom, hence the explicit kind is required
newtype LeftAdj (m :: * -> *) a = LeftAdj { unLeftAdj :: a }
instance Monad m => CFunctor (LeftAdj m) (->) (Kleisli m) where
    cfmap f = Kleisli $ liftM LeftAdj . return . f . unLeftAdj
    -- we could also express it as liftM LeftAdj . (return .) f . unLeftAdj

右邊的一個將對象a映射到對象ma並將一個態射g映射到join . liftM g join . liftM g ,或等效於(=<<) g

newtype RightAdj m a = RightAdj { unRightAdj :: m a }
instance Monad m => CFunctor (RightAdj m) (Kleisli m) (->) where
    cfmap (Kleisli g) = RightAdj . join . liftM g . unRightAdj
    -- this can be shortened as RightAdj . (=<<) g . unRightAdj

(如果有人知道如何在Haskell中表達這一點,請告訴我。)

  • Maybe是從免費的仿函數到尖頭套裝和健忘的仿函數回來
  • []來自免費的仿函數,進入幺半群和健忘的仿函數

但這些類別都不是Hask的子類別。

正如你所觀察到的,每一對伴隨的仿函數都會產生一個monad。 反之亦然:每個monad都以這種方式出現。 事實上,它以兩種規范的方式實現。 一個是Kleisli建築Petr描述的; 另一個是Eilenberg-Moore建築。 實際上,Kleisli是最初的這種方式,而EM是最終的方式,在一對合適的伴隨仿函數中。 他們是在1965年獨立發現的。如果你想要細節,我強烈推薦Catsters視頻

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM