[英]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. 有人可能会认为
ComonadApply
对Comonad
来说对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. 然而,
Applicative
用pure
方法将值注入算子的能力才是真正的区别。
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
的双extract
和bind
的双重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: 因此,如果我们看一下从
Applicative
到Monad
的步骤,那么两者之间的逻辑步骤将是一个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. 请注意,我们不能根据
extend
或duplicate
来定义extract
,也不能在bind
或join
方面定义pure
/ return
,因此这似乎是“逻辑”步骤。 apply
is mostly irrelevant here; apply
在这里大多无关紧要; it can be defined for either Extract
or Monad
, as long as their laws hold: 它可以定义为
Extract
或Monad
,只要它们的法律成立:
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
: 此外,任何同时属于
Extract
和Applicative
实例的类型都是Monad
和Comonad
,因为您可以根据extract
和pure
定义bind
和extend
:
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.