【问题标题】:Every monad is an applicative functor — generalizing to other categories每个 monad 都是一个应用函子——泛化到其他类别
【发布时间】:2018-12-27 16:39:35
【问题描述】:

我可以很容易地在 Haskell 中定义一般的 FunctorMonad 类:

class (Category s, Category t) => Functor s t f where
    map :: s a b -> t (f a) (f b)

class Functor s s m => Monad s m where
    pure :: s a (m a)
    join :: s (m (m a)) (m a)
    join = bind id
    bind :: s a (m b) -> s (m a) (m b)
    bind f = join . map f

我正在阅读this post,它解释了一个应用函子是一个松散的(封闭的或单曲面的)函子。它是根据(指数或幺半群)双函子来实现的。我知道在 Haskell 类别中,每个Monad 都是Applicative;我们如何概括?我们应该如何选择定义Applicative的(指数或幺半群)函子?让我困惑的是我们的 Monad 类似乎没有任何(封闭或单面)结构的概念。

编辑:一位评论者说这通常是不可能的,所以现在我的部分问题是它可能在哪里。

【问题讨论】:

标签: haskell categories functor applicative category-theory


【解决方案1】:

让我感到困惑的是,我们的 Monad 类似乎没有任何(封闭或单面)结构的概念。

如果我正确理解了您的问题,那将通过单子的张量强度来提供。 Monad 类没有它,因为它是 Hask 类别所固有的。更具体地说,假设是:

t :: Monad m => (a, m b) -> m (a,b)
t (x, my) = my >>= \y -> return (x,y) 

【讨论】:

  • 所以一般来说,Applicative 不是 Monad 的超类?相反,它们都是(比如说)StrongMonad 的超类? (我猜Applicative 甚至不能被定义,除非类别是幺半群?)
  • 这是我的理解。特别是 (<*>) = ap 和一般设置 ap :: (Monad m) => m (a -> b) -> m a -> m b 需要张量强度(如果我们不加咖喱,则更明显)。
【解决方案2】:

基本上,单曲面函子的方法中涉及的所有单曲面内容都发生在目标类别上。它可以这样形式化

class (Category s, Category t) => Functor s t f where
  map :: s a b -> t (f a) (f b)

class Functor s t f => Monoidal s t f where
  pureUnit :: t () (f ())
  fzip :: t (f a,f b) (f (a,b))

s-morphisms 仅在考虑幺半群函子定律时才会出现,它粗略地说s 的幺半群结构应该由函子映射到t 的这个幺半群结构。

也许更有洞察力的是将fmap 分解到类方法中,这样仿函数的“func-”部分的作用就很清楚了:

class Functor s t f => Monoidal s t f where
  ...
  puref :: s () y -> t () (f y)
  puref f = map f . pureUnit
  fzipWith :: s (a,b) c -> t (f a,f b) (f c)
  fzipWith f = map f . fzip

Monoidal,我们可以找回我们以前的Hask-Applicative,因此:

pure :: Monoidal (->) (->) f => a -> f a
pure a = puref (const a) ()

(<*>) :: Monoidal (->) (->) f => f (a->b) -> f a -> f b
fs <*> xs = fzipWith (uncurry ($)) (fs, xs)

liftA2 :: Monoidal (->) (->) f => (a->b->c) -> f a -> f b -> f c
liftA2 f xs ys = fzipWith (uncurry f) (xs,ys)

也许在这种情况下更有趣的是另一个方向,因为这向我们展示了在广义情况下与 monad 的联系:

instance Applicative f => Monoidal (->) (->) f where
  pureUnit = pure
  fzip = \(xs,ys) -> liftA2 (,) xs ys
       = \(xs,ys) -> join $ map (\x -> map (x,) ys) xs

lambda 和元组部分在一般类别中不可用,但它们可以是 translated to cartesian closed categories


我将(,) 用作两个幺半群类别中的产品,具有标识元素()。更一般地,您可以为产品及其各自的标识元素编写 data I_sdata I_ttype family (⊗) x ytype family (∙) x y

【讨论】:

  • 你可能是对的,也许我错过了一些东西。不过,看看幺半群函子的definition,自然变换 Φ: FA ⊗ FB -> F(A⊗B),对于内函子来说,似乎只是单子的力量,不是吗?不像我写的那样,但从t: A ⊗ TB -&gt; T (A⊗B) 中获得强度t': TA ⊗ TB -&gt; T (A⊗B) 非常简单。我在这里还缺少什么吗?
  • 我认为这是一个问题,使用(,)作为产品。
  • @MFarkas-Dyck 不确定。您肯定需要一些 CCC 助手来连接 monoidal-functor 和 monad 类,并且在任何 CCC 中,产品本质上将表现为一个元组(即使您不使用 Haskell 元组)。但是,如果我错了,我会很高兴看到一个反例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 2023-03-25
  • 2011-03-27
  • 1970-01-01
  • 2017-06-20
  • 2021-03-20
相关资源
最近更新 更多