Wo sind die Applicative
Transformatorklassen? Ich wollte Transformator Klassen für die applicative transformer stack in a previous answer verwenden, aber sie scheinen nicht zu existieren.Applikative Transformatorklassen
Das transformers Paket und viele andere sind voll von Transformatoren, die Applicative
Struktur erhalten, auch wenn die zugrunde liegende Struktur kein Monad
ist.
Ein kurzer Blick auf transformers
hat Applicative
Instanzen für die meisten Transformatoren.
Applicative f => Applicative (Backwards f)
Applicative f => Applicative (Lift f)
Applicative (ContT r m)
Applicative m => Applicative (IdentityT m)
Applicative m => Applicative (ReaderT r m)
(Monoid w, Applicative m) => Applicative (WriterT w m)
(Applicative f, Applicative g) => Applicative (Compose f g)
(Applicative f, Applicative g) => Applicative (Product f g)
Nur Transformatoren für Zustand und Wechsel (ExceptT
und MaybeT
) erfordern einen darunter liegenden monadisch für die Applicative
Instanz.
(Functor m, Monad m) => Applicative (ExceptT e m)
(Functor m, Monad m) => Applicative (MaybeT m)
(Monoid w, Functor m, Monad m) => Applicative (RWST r w s m)
(Functor m, Monad m) => Applicative (StateT s m)
Es gibt eine Klasse für Monad
Transformatoren. Ich kann sehen, wie etwas diese Monad
Constraint erfordern könnte, da es anderswo nicht eingeführt werden kann.
class MonadTrans t where
lift :: (Monad m) => m a -> t m a
Wo ist die Klasse für Applicative
Transformatoren?
class ApTrans t where
liftAp :: (Applicative f) => f a -> t f a
Oder einfach nur alte Transformatoren (obwohl ich mir keine Gesetze dafür vorstellen kann)?
class Trans t where
liftAny :: f a -> t f a
Aufgrund des Unterschied nur in polymorphen Zwängen hat dieser typeclasses ein seltsames Varianz Muster. Abgesehen von ihren Gesetzen, die unvorhergesehene Einschränkungen berücksichtigen müssen, sollte alles, was eine Instanz von Trans
ist, automatisch eine Instanz von ApTrans
und MonadTrans
sein, und alles, was eine Instanz von ApTrans
ist, sollte automatisch eine Instanz von MonadTrans
sein.
Wenn wir weiter zur mtl-Bibliothek gehen, sind die Klassen dort inkompatibel mit einem Applicative
Transformatorstapel. Alle mir bekannten mtl-Klassen haben eine Monad
Einschränkung. Zum Beispiel ist hier MonadReader
class Monad m => MonadReader r m | m -> r where
-- | Retrieves the monad environment.
ask :: m r
ask = reader id
-- | Executes a computation in a modified environment.
local :: (r -> r) --^The function to modify the environment.
-> m a --^@[email protected] to run in the modified environment.
-> m a
-- | Retrieves a function of the current environment.
reader :: (r -> a) --^The selector function to apply to the environment.
-> m a
reader f = do
r <- ask
return (f r)
Was ist der Zweck der Monad
Einschränkung ist? Es macht MonadReader
und die MonadReader
Instanzen für viele der oben genannten Transformatoren inkompatibel mit Applicative
Transformator-Stacks.
Ich würde naiv so etwas wie
class Reader r m | m -> r where
ask :: m r
local :: (r -> r) -> m a -> m a
oder sogar Split local
in eine eigene Klasse schreiben.
class Reader r m | m -> r where
ask :: m r
class (Reader r m) => Local r m | m -> r where
local :: (r -> r) -> m a -> m a
local
könnte sehr schwierig sein, ohne Monad
Instanz zu verwenden.Eine weitere nützliche Schnittstelle ohne die Monad
Einschränkung würde irgendwo so etwas wie
class (Reader r m) => Local r m | m -> r where
local :: m (r -> r) -> m a -> m a
Gibt es vorhandene Transformator Klassen, die die Monad
Einschränkung nicht haben, oder gibt es einen tatsächlichen Bedarf für einen weiteren Transformator Klassenbibliothek?
[Dies] (http://comonad.com/ Leser/2012/Abstracting-with-Applicatives /) ist es wert, über die Kombination von Applicates auf verschiedene Arten gelesen zu werden. – AndrewC
@AndrewC Danke, ich wünschte, ich hätte das gelesen, bevor ich versuchte, die verknüpfte Frage zu beantworten. – Cirdec
Ich denke, es gibt Anwendungstransformatoren, die nicht aus zusammensetzenden Anwendungen stammen. Definieren Sie zum Beispiel die Daten der monadischen Streams MStream m a = MStream (a, MStream m a). Dann ist "MStream Identity" ein "Applicative", und für jedes "Applicative m" ist "MStream m" ein "Applicative", und es gibt einen offensichtlichen "lift :: m a -> MStream m a" durch unendliche Wiederholung. Dennoch ist "MStream m" nicht die Zusammensetzung von "MStream" und "m"! (Übung, was ist das?) – Turion