Где классы трансформатора Applicative
? Я хотел использовать классы преобразователей для стека прикладных преобразователей в предыдущем ответе, но, похоже, их не существует.
Пакет transformers и многие другие полны преобразователей, которые сохраняют Applicative
структуру, даже если базовая структура не Monad
.
Беглый взгляд на transformers
содержит Applicative
экземпляров для большинства трансформаторов.
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)
Только преобразователи состояния и чередования (ExceptT
и MaybeT
) требуют базовой монады для экземпляра Applicative
.
(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)
Есть класс для Monad
трансформаторов. Я понимаю, как что-то может потребовать этого Monad
ограничения, поскольку его нельзя ввести в другом месте.
class MonadTrans t where
lift :: (Monad m) => m a -> t m a
Где класс для Applicative
трансформаторов?
class ApTrans t where
liftAp :: (Applicative f) => f a -> t f a
Или просто старые добрые трансформаторы (хотя я не могу себе представить для этого никаких законов)?
class Trans t where
liftAny :: f a -> t f a
Из-за разницы только в полиморфных ограничениях эти классы типов имеют странный паттерн дисперсии. За исключением их законов, которые должны учитывать невыразимые ограничения, все, что является экземпляром Trans
, должно автоматически быть экземпляром ApTrans
и MonadTrans
, а все, что является экземпляром ApTrans
, должно автоматически быть экземпляром MonadTrans
.
Если мы перейдем к библиотеке mtl, классы там также несовместимы со стеком преобразователя Applicative
. . Все классы mtl, с которыми я знаком, имеют ограничение Monad
. Например, вот 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 -- ^ @Reader@ 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)
Какова цель ограничения Monad
? Это делает экземпляры MonadReader
и MonadReader
для многих из вышеуказанных трансформаторов несовместимыми со стеками Applicative
трансформаторов.
Я бы наивно написал что-нибудь вроде
class Reader r m | m -> r where
ask :: m r
local :: (r -> r) -> m a -> m a
или даже разделить local
на отдельный класс.
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
было бы довольно сложно использовать без Monad
экземпляра. Более полезный интерфейс без ограничения Monad
выглядел бы примерно так:
class (Reader r m) => Local r m | m -> r where
local :: m (r -> r) -> m a -> m a
Существуют ли где-то существующие классы трансформаторов, которые не имеют ограничения Monad
, или существует реальная потребность в еще одной библиотеке классов трансформаторов?
data MStream m a = MStream (a, MStream m a)
. ТогдаMStream Identity
- этоApplicative
, и для любогоApplicative m
,MStream m
этоApplicative
, и есть очевидноеlift :: m a -> MStream m a
бесконечным повторением. Тем не менее,MStream m
не составMStream
иm
! (Упражнение, что это такое?) - person Turion   schedule 10.06.2016MStream m a
- этоApplicative
независимо от того, что такоеm
;m
- фантомный тип. Это то же самое, что иdata Stream a = Stream a (Stream a)
. Если вы имели в виду, чтоa
s должны быть обернутыm
, то это точно композицияApplicative
sStream
иm
,Compose Stream m
. Вот что делает композицияApplicative
s; он оборачивает каждое вхождение аргумента во внешний функтор с внутренним функтором. - person Cirdec   schedule 10.06.2016MStream m (a, MStream m a)
!! - person Turion   schedule 11.06.2016Mstream Identity (m a) = (Compose Stream m) a
. - person Turion   schedule 11.06.2016Applicative
с определенной структурой, я предлагаю вам задать отдельный вопрос. Ваше исправление все еще содержит опечатки, и хотя я мог догадаться, что вы имеете в виду, и отсылаю вас к базовым функторам и фиксированным точкам, это превышает то, что я готов развлечь в комментариях. - person Cirdec   schedule 11.06.2016