![](/img/trans.png)
[英]What kind of structure is this? (Monad with a partial inverse but not a comonad)
[英]Applicative is to monad what X is to comonad
我们可以为X解决这个等式吗?
适用于monad是什么X是comonad
在考虑之后,我认为这实际上是一个落后的问题。 有人可能会认为ComonadApply
对Comonad
来说对Monad
什么Applicative
,但事实并非如此。 但是要看到这一点,让我们使用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
请注意,我们不能根据extend
或duplicate
来定义extract
,也不能在bind
或join
方面定义pure
/ return
,因此这似乎是“逻辑”步骤。 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
尚不存在。 但在2010年的报告中也没有Applicative
。 此外,任何同时属于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
*能够在extract
方面定义apply
是一个标志, class Extend w => Comonad w
可能更可行,但是可以将Monad
分成class (Applicative f, Bind f) => Monad f
,因此Comonad
into (Extend w, Extract w) => Comonad w
,所以它或多或少分裂头发。
对我来说,似乎Apply
类不应该是图片的一部分。
例如,在@ Zeta的答案中, apply
的定义似乎没有得到很好的表现。 特别是,它总是丢弃第一个参数的上下文,并且只使用第二个参数的上下文。
直觉上,似乎comonad是关于“分裂”上下文而不是组合,因此“共同应用”应该是相同的。
这个问题似乎有更好的答案: 是否存在类似共同应用仿函数的概念,它们位于comonads和functor之间? 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.