13

我们可以为 X 解这个方程吗?

Applicative 是 monad 就像 X 是 comonad

4

2 回答 2

9

经过一番思考,我认为这实际上是一个落后的问题。有人可能认为那ComonadApplyComonad什么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'dualextractbind'dual (或通过as 's dualextend的替代定义)组成:duplicatejoin

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

因此,如果我们查看 fromApplicativeMonad的步骤,之间的逻辑步骤将是具有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

请注意,我们不能extractextendorduplicate来定义,也不能用 or 来定义/ purereturn所以这似乎是“合乎逻辑”的步骤。在这里几乎无关紧要;它可以定义为或,只要它们的定律成立:bindjoinapplyExtractMonad

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(获取价值)是MonadApply或多或少是一个快乐的小意外。有趣的是 Hask 中是否有类型有Extract,但没有Comonad(或Extend但没有Comonad,见下文),但我想这些是相当罕见的。

请注意,Extract尚不存在。但Applicative2010 年的报告中也没有。此外,任何既是 of 的实例ExtractApplicative是自动的类型既是 aMonad又是 a Comonad,因为您可以根据bindandextend定义extractand 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    

* 能够根据 来定义applyextract一个更可行的符号class Extend w => Comonad w,但是一个人可能已经分裂Monadclass (Applicative f, Bind f) => Monad f并因此分裂Comonad(Extend w, Extract w) => Comonad w,所以它或多或少是分裂的头发。

于 2016-01-19T20:21:02.380 回答
0

在我看来,Apply课堂似乎根本不应该成为画面的一部分。

例如apply,@Zeta 的答案中的定义似乎并不乖巧。特别是,它总是丢弃第一个参数的上下文,只使用第二个参数的上下文。

直觉上,comonad 似乎是关于“拆分”上下文而不是组合,因此“co-applicative”应该是相同的。

这个问题似乎有更好的答案:在共单子和函子之间是否有类似共同应用函子的概念?.

于 2019-04-17T13:03:29.847 回答