Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell中与公共单子对应的伴随函子对是什么?_Haskell_Category Theory - Fatal编程技术网

Haskell中与公共单子对应的伴随函子对是什么?

Haskell中与公共单子对应的伴随函子对是什么?,haskell,category-theory,Haskell,Category Theory,在范畴论中,一个单子可以由两个伴随函子构成。特别是,如果C和D是类别,而F:C-->D和G:D-->C是伴随函子,则在存在双射的意义上 hom(FX,Y)=hom(X,GY) 对于C中的每个X和D中的每个Y,组合gof:C-->C是一个单子 通过固定类型b并将F和G取为 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) in

在范畴论中,一个单子可以由两个伴随函子构成。特别是,如果C和D是类别,而F:C-->D和G:D-->C是伴随函子,则在存在双射的意义上

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

对于C中的每个X和D中的每个Y,组合gof:C-->C是一个单子


通过固定类型
b
并将
F
G
取为

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)
hom集之间的双射通过下列公式给出(模构造函数):

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)
我不知道这个单子的名字应该是什么,除了它看起来像一个读卡器单子,它携带了一段可写的信息(edit:dbaupp在评论中指出这是
状态
monad)

因此,
状态
单子可以“分解”为一对伴随函子
F
G
,我们可以编写

State = G . F
到目前为止,一切顺利


我现在正试图找出如何将其他常见的单子分解成成对的伴随函子-例如,
也许
[]
读取器
编写器
Cont
-但我无法找出我们可以将它们“分解”成的成对伴随函子

唯一简单的情况似乎是
Identity
单子,它可以分解为任何一对函子
F
G
,这样
F
G
是相反的(特别是,你可以取
F=Identity
G=Identity


有人能解释一下吗?

你要找的是。它最初是为了证明每个单子都可以由两个伴随函子构成

问题是Haskell
函子
不是泛型函子,而是Haskell范畴中的内函子。因此,我们需要一些不同的(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)
请注意,如果我们对
c
d
都使用
->
,我们会得到一个Haskell类的内函子,它就是
fmap
的类型:

cfmap :: (a -> b) -> (f a -> f b)
现在我们有了显式类型类,它表示两个给定类别
c
d
之间的函子,我们可以表示给定单子的两个伴随函子。左图将对象
a
映射到just
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
映射到
连接。liftM g
,或等效于
(=),其中
cfmap(Kleisli g)=右调整。参加liftM g。不公正的
--这可以缩短为rightaj。(=
  • 可能
    来自自由函子,属于点集范畴,而健忘函子又回到了点集范畴
  • []
    来自自由函子,属于幺半群的范畴,而健忘函子又回来了

但这两个范畴都不是哈斯克的子范畴。

正如你所观察到的,每对伴随函子都会产生一个单子。反之亦然:每一个单子都是以这种方式产生的。事实上,它以两种规范的方式产生。一种是佩特描述的克莱斯利构造;另一种是艾伦伯格-摩尔构造。的确,克莱斯利s是最初的这种方式,E-M是最终的方式,在一对合适的伴随函子中。它们是在1965年独立发现的。如果你想知道细节,我强烈推荐。

你构造的单子就是状态单子。啊,当然。我会把它添加到我的单子列表中“有几次我在没有意识到的情况下重新发明了一个著名的monad实例。“将一个单子分解为指定函子的组合并不是唯一的,事实上,对于任何一个单子,都有一个完整的此类分解类别。可能最有用的两种分解是终端分解和初始分解:右伴随是(1)单子代数范畴中的健忘函子(Eilenberg-Moore类别)和(2)单子的自由代数类别(Kleisli类别)。@Omar:这个类别叫什么?@Sebastien:我认为它没有一个完全标准化的名称,但如果你称它为“单子的附加类别”每个人都会知道你的意思。谢谢Tom。我已经完成了这两个函数的细节——现在,我想知道其他例子中对应的函子是什么。而
contr
来自逆变函子opr:Hask^Op-->Hask本身的附加,opra=a->r。很确定这两个都是Eilenb感谢杰里米——有几个人向我推荐了猫咪,我真的应该去看看。艾伦伯格·摩尔为州立单子所做的附属品的F-| 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