Подтвердить что ты не робот

Аппликация заключается в монаде, что X является comonad

Можем ли мы решить это уравнение для X?

Аппликация - это монада, что X является comonad

4b9b3361

Ответ 1

Подумав немного, я думаю, что это на самом деле задний вопрос. Можно подумать, что 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 и двойного extend bind (или альтернативного определения через 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 является Comonad что Applicative (получение значений) для Monad. Apply это более или менее счастливый случай на своем пути. Было бы интересно, есть ли в Hask типы, которые имеют Extract, но не Comonad (или Extend но не Comonad, см. Ниже), но я думаю, что они довольно редки.

Обратите внимание, что Extract не существует - пока. Но ни один не сделал Applicative в отчете за 2010 год. Кроме того, любой тип, который одновременно является экземпляром 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, чтобы он более-менее раскалывал волосы.

Ответ 2

Мне кажется, что класс Apply вообще не должен быть частью картины.

Например, определение apply в ответе @Zeta выглядит не очень корректно. В частности, он всегда отбрасывает контекст первого аргумента и использует только контекст второго аргумента.

Интуитивно кажется, что comonad - это "разделение" контекста, а не объединение, и поэтому "совместное применение" должно быть одинаковым.

На этот вопрос, кажется, есть лучшие ответы: существует ли понятие комападативных функторов, сидящих между комонадами и функторами? ,