简体   繁体   English

适用于monad是什么X是comonad

[英]Applicative is to monad what X is to comonad

Can we solve this equation for X ? 我们可以为X解决这个等式吗?

Applicative is to monad what X is to comonad 适用于monad是什么X是comonad

After giving it some thought, I think this is actually a backward question. 在考虑之后,我认为这实际上是一个落后的问题。 One might think that ComonadApply is to Comonad what Applicative is to Monad , but that is not the case. 有人可能会认为ComonadApplyComonad来说对Monad什么Applicative ,但事实并非如此。 But to see this, let us use PureScript's typeclass hierarchy: 但是要看到这一点,让我们使用PureScript的类型类层次结构:

class Functor f where
    fmap :: (a -> b) -> f a -> f b

class Functor f => Apply f where
    apply :: f (a -> b) -> f a -> f b -- (<*>)

class Apply f => Applicative f where
    pure :: a -> f a

class Applicative m => Monad m where
    bind :: m a -> (a -> m b) -> m b  -- (>>=)
 -- join :: m (m a) -> m a
 -- join = flip bind id

As you can see, ComonadApply is merely (Apply w, Comonad w) => w . 如您所见, ComonadApply仅仅是(Apply w, Comonad w) => w However, Applicative 's ability to inject values into the functor with pure is the real difference. 然而, Applicativepure方法将值注入算子的能力才是真正的区别。

The definition of a Comonad as the categorical dual consists of return 's dual extract and bind 's dual extend (or the alternative definiton via duplicate as join 's dual): Comonad作为分类对偶的定义包括return的双extractbind的双重extend (或者通过duplicate的替代定义作为join对偶):

class Functor w => Comonad w where
    extract   :: w a -> a        
    extend    :: (w a -> b) -> w a -> w b
 -- extend f  = fmap f . duplicate k
 -- duplicate :: w a -> w (w a)
 -- duplicate = extend id

So if we look at the step from Applicative to Monad , the logical step between would be a typeclass with pure 's dual: 因此,如果我们看一下从ApplicativeMonad的步骤,那么两者之间的逻辑步骤将是一个pure的双重类型:

class Apply w => Extract w where
    extract :: w a -> a

class Extract w => Comonad w where
    extend :: (w a -> b) -> w a -> w b

Note that we cannot define extract in terms of extend or duplicate , and neither can we define pure / return in terms of bind or join , so this seems like the "logical" step. 请注意,我们不能根据extendduplicate来定义extract ,也不能在bindjoin方面定义pure / return ,因此这似乎是“逻辑”步骤。 apply is mostly irrelevant here; apply在这里大多无关紧要; it can be defined for either Extract or Monad , as long as their laws hold: 它可以定义为ExtractMonad ,只要它们的法律成立:

applyC f = fmap $ extract f   -- Comonad variant; needs only Extract actually (*)
applyM f = bind f . flip fmap -- Monad variant; we need join or bind

So Extract (getting values out) is to Comonad what Applicative (getting values in) is to Monad . 因此, Extract (获取值)对于Comonad是什么Applicative (获取值)是Monad Apply is more or less a happy little accident along the way. Apply或多或少是一个快乐的小事故。 It would be interesting whether there are types in Hask that have Extract , but not Comonad (or Extend but not Comonad , see below), but I guess those are rather rare. Hask中是否有类型具有Extract ,而不是Comonad (或者是Extend但不是Comonad ,见下文)会很有趣,但我想这些是相当罕见的。

Note that Extract doesn't exist—yet. 请注意, Extract尚不存在。 But neither did Applicative in the 2010 report . 但在2010年的报告中也没有Applicative Also, any type that is both an instance of Extract and Applicative automatically is both a Monad and a Comonad , since you can define bind and extend in terms of extract and pure : 此外,任何同时属于ExtractApplicative实例的类型都是MonadComonad ,因为您可以根据extractpure定义bindextend

bindC :: Extract w => w a -> (a -> w b) -> w b
bindC k f = f $ extract k

extendM :: Applicative w => (w a -> b) -> w a -> w b
extendM f k = pure $ f k    

* Being able to define apply in terms of extract is a sign that class Extend w => Comonad w could be more feasible, but one could have split Monad into class (Applicative f, Bind f) => Monad f and therefore Comonad into (Extend w, Extract w) => Comonad w , so it's more or less splitting hair. *能够在extract方面定义apply是一个标志, class Extend w => Comonad w可能更可行,但是可以将Monad分成class (Applicative f, Bind f) => Monad f ,因此Comonad into (Extend w, Extract w) => Comonad w ,所以它或多或少分裂头发。

To me it seems that Apply class should not be a part of the picture at all. 对我来说,似乎Apply类不应该是图片的一部分。

For example the definition of apply in @Zeta's answer does not seem to be well-behaved. 例如,在@ Zeta的答案中, apply的定义似乎没有得到很好的表现。 In particular, it always discards the context of the first argument and only uses the context of the second argument. 特别是,它总是丢弃第一个参数的上下文,并且只使用第二个参数的上下文。

Intuitively, it seems that comonad is about "splitting" the context instead of combining, and so "co-applicative" should be the same. 直觉上,似乎comonad是关于“分裂”上下文而不是组合,因此“共同应用”应该是相同的。

This question seems to have better answers: Is there a concept of something like co-applicative functors sitting between comonads and functors? 这个问题似乎有更好的答案: 是否存在类似共同应用仿函数的概念,它们位于comonads和functor之间? .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM