我们可以为 X 解这个方程吗?
Applicative 是 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
是真正的区别。
aComonad
作为分类对偶的定义由return
'dualextract
和bind
'dual (或通过as 's dualextend
的替代定义)组成: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
因此,如果我们查看 fromApplicative
到Monad
的步骤,之间的逻辑步骤将是具有pure
's 对偶的类型类:
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
orduplicate
来定义,也不能用 or 来定义/ 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 年的报告中也没有。此外,任何既是 of 的实例Extract
又Applicative
是自动的类型既是 aMonad
又是 a Comonad
,因为您可以根据bind
andextend
定义extract
and 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
课堂似乎根本不应该成为画面的一部分。
例如apply
,@Zeta 的答案中的定义似乎并不乖巧。特别是,它总是丢弃第一个参数的上下文,只使用第二个参数的上下文。
直觉上,comonad 似乎是关于“拆分”上下文而不是组合,因此“co-applicative”应该是相同的。
这个问题似乎有更好的答案:在共单子和函子之间是否有类似共同应用函子的概念?.