Können wir diese Gleichung für X lösen?Applicative ist zu monad, was X zu comonad ist
Applicative ist zu Monade, was X
Können wir diese Gleichung für X lösen?Applicative ist zu monad, was X zu comonad ist
Applicative ist zu Monade, was X
Nach einigem Überlegen comonad ist, denke ich, das ist eigentlich eine Rückwärts Frage. Man könnte meinen, dass ComonadApply
zu Comonad
gehört, was Applicative
zu Monad
ist, aber das ist nicht der Fall. Aber um dies zu sehen, lassen Sie uns PURESCRIPT der Hierarchie typeclass verwenden:
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
Wie Sie sehen können, ComonadApply
ist lediglich (Apply w, Comonad w) => w
. Allerdings ist Applicative
die Fähigkeit, Werte in den Funktor mit pure
zu injizieren, der wirkliche Unterschied.
Die Definition eines Comonad
als kategorische Dual besteht aus return
's Dual extract
und bind
' s Dual extend
(oder die alternative definiton über duplicate
als join
‚s dual):
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
Also, wenn wir Blick auf den Schritt von Applicative
zu Monad
wäre der logische Schritt zwischen einem typeclass sein mit pure
‚s dual:
class Apply w => Extract w where
extract :: w a -> a
class Extract w => Comonad w where
extend :: (w a -> b) -> w a -> w b
Beachten Sie, dass wir nicht extract
in Bezug auf extend
oder duplicate
definieren können, und weder können wir pure
/return
in Bezug auf bind
oder join
definieren, so erscheint dies wie der „logische“ Schritt. apply
ist hier meistens irrelevant; es kann entweder für Extract
oder Monad
definiert werden, solange ihre Gesetze halten:
applyC f = fmap $ extract f -- Comonad variant; needs only Extract actually (*)
applyM f = bind f . flip fmap -- Monad variant; we need join or bind
So Extract
(Werte Aussteigen) zu Comonad
ist, was Applicative
(immer Werte in) zu Monad
ist. Apply
ist mehr oder weniger ein glücklicher kleiner Unfall auf dem Weg. Es wäre interessant, ob es in Hask Typen gibt, die Extract
haben, aber nicht Comonad
(oder Extend
, aber nicht Comonad
, siehe unten), aber ich denke, das sind eher selten.
Beachten Sie, dass Extract
nicht existiert — noch. Aber auch nicht Applicative
in der 2010 report. Auch, dass jeder Typ ist sowohl eine Instanz von Extract
und Applicative
automatisch sowohl ein Monad
und ein Comonad
, da Sie bind
und extend
in Bezug auf extract
und pure
definieren:
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
* In der Lage zu definieren apply
in Bezug auf extract
ist ein Zeichen, dass class Extend w => Comonad w
könnte mehr machbar sein, aber könnte man Monad
in class (Applicative f, Bind f) => Monad f
und damit Comonad
in (Extend w, Extract w) => Comonad w
geteilt haben, so ist es mehr oder weniger Haarspaltung.
'ComonadApply ist zu Comonad wie Applicativ zu Monad.' http://hackage.haskell.org/package/comonad-4.2.7.2/docs/Control-Comonad.html#t:ComonadApply Es scheint nicht ganz anders als Applicative ... – danidiaz
klingt wie eine Antwort! – nicolas
@danidiaz Ich sehe, dass eine 'ComonadApply' eine' Comonad' sein muss - im Gegensatz zu 'Applicative', die nicht' Monad's sein müssen. Das sieht für mich als Hauptunterschied aus. – chi