我们可以为X解决这个等式吗?
适用于monad是什么X是comonad
在考虑之后,我认为这实际上是一个落后的问题。人们可能会认为ComonadApply
是Comonad
Applicative
是什么Monad
,但事实并非如此。但是要看到这一点,让我们使用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
如你所见,ComonadApply
仅仅是(Apply w, Comonad w) => w
。然而,Applicative
用pure
将值注入算子的能力才是真正的区别。
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
因此,如果我们看看从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
请注意,我们不能用extract
或extend
定义duplicate
,也不能用pure
或return
定义bind
/ join
,所以这似乎是“逻辑”步骤。 apply
在这里几乎无关紧要;它可以定义为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
所以Extract
(获得价值)是Comonad
Applicative
(获得价值)是Monad
。 Apply
或多或少是一个幸福的小事故。 Hask中是否有类型有Extract
,而不是Comonad
(或Extend
但不是Comonad
,见下文)会很有趣,但我想这些是相当罕见的。
请注意,Extract
尚不存在。但是Applicative
的2010 report也没有。此外,任何类型都是Extract
和Applicative
的实例自动是Monad
和Comonad
,因为你可以用bind
和extend
定义extract
和pure
:
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
*能够用apply
定义extract
是class Extend w => Comonad w
可能更可行的标志,但是可以将Monad
分成class (Applicative f, Bind f) => Monad f
,因此将Comonad
分成(Extend w, Extract w) => Comonad w
,所以它或多或少分裂头发。
对我来说,似乎Apply
类不应该是图片的一部分。
例如,在@ Zeta的回答中apply
的定义似乎没有得到很好的表现。特别是,它总是丢弃第一个参数的上下文,并且只使用第二个参数的上下文。
直觉上,似乎comonad是关于“分裂”上下文而不是组合,因此“共同应用”应该是相同的。
这个问题似乎有更好的答案:Is there a concept of something like co-applicative functors sitting between comonads and functors?。